Iterator迭代器接口
迭代器(Iterator)是一种机制(接口):为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作(for…of)循环,依次处理该数据结构的所有成员。
- 底层机制:
- 迭代器接口是定义在Symbol.iterator属性上的一个方法
- 迭代器接口拥有一个next方法用于依次遍历数据结构的成员
- 每一次遍历返回的结果是一个对象{ value: xxx, done: false }
- done:记录是否完成遍历。未完成,值为false;完成,值为true
- value:当前遍历的结果
- 最后一次遍历结束后,返回的结果为{ value: undefined, done: true },并且以后再调用next方法返回的结果都是这个
- 拥有Symbol.iterator属性的数据结构(值),被称为可被遍历的,可以基于for…of循环处理
- 数组
- 部分类数组:arguments/NodeList/HTMLCollection…
- String
- Set
- Map
- generator object
- …
- 对象默认不具备Symbol.iterator,属于不可被遍历的数据结构
自己实现Iterator类
class Iterator {
constructor (assemble) {
let self = this;
self.assemble = assemble;
self.index = 0;
}
next() {
let self = this,
assemble = self.assemble;
if (self.index >= assemble.length - 1) {
return {
value: undefined,
done: true
};
}
return {
value: assemble[self.index++],
done: false
}
}
}
let itor = new Iterator([10, 20, 30, 40]);
console.log(itor.next()); //->{value:10,done:false}
console.log(itor.next()); //->{value:20,done:false}
console.log(itor.next()); //->{value:30,done:false}
console.log(itor.next()); //->{value:40,done:false}
console.log(itor.next()); //->{value:undefined,done:true}
让对象也具备迭代器接口
Object.prototype[Symbol.iterator] = function () {
let assemble = this,
keys = Object.keys(assemble).concat(Object.getOwnPropertySymbols(assemble)),
index = 0;
return {
next() {
if (index >= keys.length) {
return {
value: undefined,
done: true
}
}
return {
value: assemble[keys[index++]],
done: false
}
}
}
}
let obj = {
name: 'aaa',
age: 12,
teacher: 'team'
};
for (let value of obj) {
console.log(value);
}
让类数组具有Iterator接口
可以采取方法借用的方式
let obj = {
0: 10,
1: 20,
2: 30,
length: 3
};
obj[Symbol.iterator] = Array.prototype[Symbol.iterator];
for (let item of obj) {
console.log(item);
}