迭代器(Iterator):它是一種接口,爲各類不一樣的數據結構提供統一的訪問機制。任何數據結構,只要部署了Iterator接口,就能夠完成遍歷(這裏主要指for...of)操做。數組
在ES6中,有三類數據結構原生具有Iterator接口:數組、相似數組的對象、以及Set和Map結構。bash
爲了讓一個對象可遍歷,咱們須要爲這個對象添加一個名爲Symbol.iterator的方法(一個特殊的內置標記)。 想要讓for...of去循環這個對象必須通過下列步驟:數據結構
如下是模擬next方法返回值的例子函數
let arr = [5,10,15];
function Iterator(arr) {
let index = 0;
return {
next () {
if(index < arr.length) {
return {value: arr[index++],done: false};
} else {
return {value: undefined,done: false};
}
}
}
}
let it = Iterator(arr);
console.log(it.next()); //{value: 5, done: false}
console.log(it.next()); //{value: 10, done: false}
console.log(it.next()); //{value: 15, done: false}
console.log(it.next()); //{value: undefined, done: false}
console.log(it.next()); //{value: undefined, done: false}
複製代碼
以上代碼定義了一個Iterator函數,這個函數是遍歷器生成函數(至關於Symbol.iterator方法),以後會說到Symbol.iterator方法,調用這個函數時,會返回一個迭代器對象。再調用next()方法就會返回{value:'任何值',done:Boolean}對象。next方法用來移動指針,第一次調用時,指針指向數組的第一個位置;第二次調用時,指向第二個位置......這樣就能夠遍歷到數組的每個位置,進而獲取數組的每一個元素的值ui
let arrayLike = {
0: 'name',
1: 'age',
2: 'address',
length: 3
};
Object.prototype[Symbol.iterator] = function () {
let index = 0;
let current = this;
return {
next () {
if(index < current.length) {
return {value: current[index++], done: false};
} else {
return {value: undefined, done: true}
}
}
}
};
//這樣當使用for...of循環時會去自動調用Symbol.iterator()方法,返回一個迭代器對象以後
//又會去調用next方法
for(let i of arrayLike) {
console.log(i); //name age address
}
複製代碼
還能夠經過類部署Iterator接口。Symbol.iterator屬性對於一個函數,執行後返回當前對象的迭代器對象。this
class Iterator {
constructor (obj) {
this.start = 0;
this.end = obj.length
}
[Symbol.iterator] () {
return this;
}
next () {
if(this.start < this.end) {
return {value: obj[this.start++], done: false};
} else {
return {value: undefined, done: true};
}
}
}
let obj = {
0: 'name',
1: 'age',
length: 2
};
let it = new Iterator(obj);
// console.log(it.next());
// console.log(it.next());
// console.log(it.next());
for(let j of it) {
console.log(j); //name age
}
複製代碼
對於相似數組的對象(存在鍵值名和length屬性),部署Iterator接口有一個的簡便方法就是對象的Symbol.iterator直接引用數組的Symbol.iterator。以下所示:spa
let obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[Symbol.iterator]: Array.prototype[Symbol.iterator]
};
for(let j of obj) {
console.log(j); //將會打印出a,b,c
}
複製代碼
注意普通對象部署Symbol.iterator方法並沒有效果 prototype
字符串也是能夠迭代的 : for...of循環能夠將字符串的每一個字符循環出來指針
let str = 'hello';
for(let j of str) {
console.log(j); // h e l l o
}
複製代碼