Iterator是什么?
Iterator
是一种接口机制,为各种不同的数据结构提供统一的访问机制,使数据成员能够按照某种次序排列。并且ES6
提供了一个新的遍历命令——for...of循环,Iterator
接口主要供for...of使用。
JavaScript表示集合的数据结构主要是数组和对象,ES6
又提供了Map和Set。
Iterator
的遍历过程如下:
- 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器
Iterator
本质上就是一个指针对象。 - 第一次调用指针对象的next()方法,可以将指针指向数据结构的第一个成员。
- 第二次调用指针对象的next()方法,可以将指针指向数据结构的第二个成员。
- ...
- 持续调用next()方法,直到最后一个成员。
每次调用next方法就会返回一个对象,这个对象有两个属性,分别是done和value,done属性的值是一个Boolean值,标识着下面是否还有成员。如果下面还有成员则为true,如果没有就是false,value的值是该指针指向的值。
JavaScript中原生部署Iterator接口的数据结构都有哪些?
- Array
- Map
- Set
- String
TypedArray
- 函数的arguments对象
NodeList
对象
实现遍历器
一个对象如果要具备可被for...of循环调用的接口,就必须在Symbol.iterator
的属性上部署遍历器生成方法。当然该方法部署在原型上也可以。
class Iterator {
constructor(assemble) {
let self = this;
self.assemble = assemble;
self.index = 0;
}
//在`Symbol.iterator`的属性上部署遍历器生成方法,供for...of调用
[Symbol.iterator]() {
return this;
}
next() {
let self = this,
assemble = self.assemble,
index = self.index;
if (index > assemble.length - 1) {
return {
done: true,
value: undefined,
};
} else {
return {
done: false,
value: assemble[self.index++],
};
}
}
}
let obj = {
0: "a",
1: "b",
2: "c",
length: 3,
};
for (const value of new Iterator(obj)) {
console.log(value);//a,b,c
}
//如果直接使用下面
//for (const value of obj) {
// console.log(value);
//}
//会报Uncaught TypeError: obj is not iterable
从上面代码我们可以看出来,Iterator对象需要有next()方法。
对于一个对象部署方法实际上就是执行下面代码
let iterator = {
0: "a",
1: "b",
2: "c",
length: 3,
[Symbol.iterator]: function() {
const self = this;
let index = 0;
return {
next() {
if (index > self.length - 1) {
return {
done: true,
value: undefined,
};
} else {
return {
done: false,
value: self[index++],
};
}
},
};
},
};
for (const value of iterator) {
console.log(value);//a,b,c
}
obj是一个对象集合,可以说是一个类数组对象。部署后iterator接口后可以使用for...of循环调用
还有一个方式是直接使用数组对象的遍历器方法
let iterator={
0:"a",
1:"b",
2:"c",
length:3,
[Symbol.iterator]:Array.prototype[Symbol.iterator]
}
遍历器对象还有另外两个方法
-
return()
如果for...of循环提前退出(通常是因为出错,或者break语句,或者continue语句),如果一个对象在完成遍历前需要清理或者释放资源,就可以部署return 方法,另外,return必须返回一个对象,这是Generator规则决定的
-
throw()
很少用到,且听下回Generator章节
默认调用Iterator接口的其他场合
- 解构赋值
- 扩展运算符
- yield*
- for...of
Array.from()
- Map(),Set(),
WeekMap()
,WeekSet()
; promise.all()
promise.race()
与其他遍历语法的比较
- for循环:缺点就是写法麻烦
- forEach:无法跳出循环,break,return都无效
- for...in它更见适合遍历对象,它以字符串作为键名,不仅会遍历当前对象上的键值,还会遍历原型上的键值,for...in循环遍历顺序不统一
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!