概念##
JavaScript原有的表示“集合”的數據結構盖奈,主要是數組(Array)和對象(Object)谣光,ES6又添加了Map和Set肆饶。這樣就有了四種數據集合,用戶還可以組合使用它們赔退,定義自己的數據結構,比如數組的成員是Map钢颂,Map的成員是對象经窖。這樣就需要一種統一的接口機制,來處理所有不同的數據結構彭沼。
它是一種接口缔逛,為各種不同的數據結構提供統一的訪問機制。
任何數據結構只要部署Iterator接口姓惑,就可以完成遍歷操作(即依次處理該數據結構的所有成員)褐奴。
在ES6中,有三類數據結構原生具備Iterator接口:數組于毙、某些類似數組的對象敦冬、Set和Map結構。
Iterator的作用有三個##
為各種數據結構唯沮,提供一個統一的脖旱、簡便的訪問接口;
使得數據結構的成員能夠按某種次序排列烂翰;
- ES6創(chuàng)造了一種新的遍歷命令for...of循環(huán)夯缺,Iterator接口主要供for...of消費。
模擬Iterator##
var it = makeIterator(['a', 'b']);
it.next() // { value: "a", done: false }
it.next() // { value: "b", done: false }
it.next() // { value: undefined, done: true }
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{value: undefined, done: true};
}
};
}
在ES6中甘耿,有些數據結構原生具備Iterator接口(比如數組)踊兜,即不用任何處理,就可以被for...of循環(huán)遍歷佳恬,有些就不行(比如對象)捏境。原因在于,這些數據結構原生部署了Symbol.iterator屬性(詳見下文)毁葱,另外一些數據結構沒有垫言。凡是部署了Symbol.iterator屬性的數據結構,就稱為部署了遍歷器接口倾剿。調用這個接口筷频,就會返回一個遍歷器對象。
Symbol.iterator屬性本身是一個函數前痘,就是當前數據結構默認的遍歷器生成函數凛捏。執(zhí)行這個函數,就會返回一個遍歷器芹缔。
對于類似數組的對象(存在數值鍵名和length屬性)坯癣,部署Iterator接口,有一個簡便方法最欠,就是Symbol.iterator方法直接引用數組的Iterator接口示罗。
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
// 或者
NodeList.prototype[Symbol.iterator] = [][Symbol.iterator];
[...document.querySelectorAll('div')] // 可以執(zhí)行了
下面是類似數組的對象調用數組的Symbol.iterator方法的例子惩猫。
let iterable = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for (let item of iterable) {
console.log(item); // 'a', 'b', 'c'
}
調用Iterator接口的場合##
有一些場合會默認調用Iterator接口(即Symbol.iterator方法),除了下文會介紹的for...of循環(huán)蚜点,還有幾個別的場合轧房。
(1)解構賦值
(2)擴展運算符
參考博客