笔记,总结摘录自阮一峰
Iterator基本概念
Iterator(遍历器)是一种接口,为不同的数据结构提供统一的遍历机制。
主要供for...of...
循环使用。
一个例子来说明,遍历器生成函数和遍历器对象:
比如对某数组arr
进行for...of...
操作,会调用arr
上的Symbol.iterator
函数,返回一个遍历器对象,供for...of...
遍历。
一个遍历器对象应必须有next()
方法,可以有也可以没有return()
,throw()
方法。
遍历过程:
- 创建一个指针对象,指向
arr
的起始位置,也就是说,遍历器本质上,就是一个指针对象。 - 第一次调用指针对象的
next()
方法,可以将指针指向数据结构的第一个成员 - 第二次低啊用指针对象的
next()
方法,指向第二个成员 - 多次调用,直到数据结构的尾部。
每次调用next()方法,都会返回一个包含value
,done
两个属性的对象。value
是当前成员,done
是一个布尔值,表示遍历是否结束(为true时,表示结束)。
根据以上过程,可以总结如下
- ES6的遍历操作本质上是调用了
Symbol.iterator
接口,这样的操作有 - 结构赋值
- 扩展运算符(...)
- yield*
for...of...
- ES6中以数组作为参数的情况
- 有的数据结构原生具有遍历器接口,我们可以直接调用,。
原生具有遍历器接口的有: - 数组
- Set、Map结构
- 某些类数组对象(字符串、DOM NodeLIst、
arguments
) - Generator 对象
- 而没有原生遍历器接口的,可以通过自定义
Symbol.iterator
函数,来实现。
Iterator接口与Generator函数
var myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
[...myIterable] // [1, 2, 3]
// 或者采用下面的简洁写法
let obj = {
* [Symbol.iterator]() {
yield 'hello';
yield 'world';
}
};
for (let x of obj) {
console.log(x);
}
// hello
// world
for...of
与for...in
for...in
遍历操作:为对象遍历设计的,并不非常适用于数组。当遍历数组时会存在以下问题:数组键名是数字,但是
for...in
循环以字符串作为键名‘0’,‘1’,‘2’for...in
循环不仅遍历数字键名,还会遍历手动添加的其他键,也包括原型链上的键某些情况下,
for...in
循环会以任意顺序遍历键名。for...of
解决了以上的问题。可以配合数组、Set等结构的
entries()
、keys()
、values()
方法,实现不同的遍历。不存在
for...in
的缺点。可以正确识别32位UTF-16字符