迭代器(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
}
复制代码