Iterator和for…of循环
Iterator:是一种机制,也是一种接口,任何数据结构只要部署了Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)
Iterator的作用:
1.为各种数据提供一个统一的,简便的访问接口
2.使得数据结构的成员能够按某种次序排序
3.for…of循环,Iterator接口主要供for…of消费
Iterator的遍历过程:
1.创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上就是一个指针对象
2.第一次调用指针对象的next方法,指针就指向数据结构的第一个成员,每次调用向后指一个
3.不断调用指针对象的next方法,直到它指向数据结构的结束位置
ps:每一次调用next都返回当前成员的信息,包含value和done两个属性的对象,value是当前成员的值,done是布尔值,表示遍历是否结束
ES6规定,默认的Iterator接口部署在数据结构的Symbol.iterator属性,即一个数据只要有symbol.iterator属性,就可认为它是“可遍历的”
在ES6中,有3类数据结构原生具备Iterator接口:数组、某些类似数组的对象,set,map(普通对象不能直接部署symbol.iterator接口)
eg1:1
2
3
4
5
6
7
8
9
10let iterable = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
[symbol.iterator]:Array.prototype[symbol.iterator]
};
for(let item of iterable){
console.log(item); // 'a','b','c'
}
eg2:1
2
3
4
5
6
7
8
9
10let iterable = {
a: 'a',
b: 'b',
c: 'c',
length: 3,
[symbol.iterator]:Array.prototype[symbol.iterator]
};
for(let item of iterable){
console.log(item); // undefined,undefined,undefined
}
如果symbol.iterator方法对应的不是遍历器生成函数(即会返回一个遍历器对象),解释引擎将报错
调用Iterator接口的场合
1.解构赋值
对数组和Set结构进行解构赋值是,会默认调用Symbol.iterator方法
eg:1
2
3
4
5
6let set = new Set().add('a').add('b').add('c');
let [x,y] = set;
// x = 'a';y = 'b'
let [first,...rest] = set;
//first = 'a';rest = ['b','c'];
2.扩展运算符
扩展运算符也会调用默认的Iterator接口
eg1:1
2var str = 'hello';
[...str] // ['h','e','l','l','o']
3.yield*
yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
其他场合
由于数组的遍历会调用遍历器接口,所以任何接受数组为参数的场合其实都调用了遍历器接口
eg:1
2
3
4
5for...of
Array.from()
Map()、Set()、WeakMap()、WeakSet()
Promise.all()
Promise.race()
ps:遍历器还可以具有return()和throw()方法,可手动部署。 如果for…of循环提前退出,就会调用return方法
ps:javascript原有的for…in循环只能获取键名不能获取键值,而for…of可以获取键值(for…of可通过entries()和keys()方法实现获取数组索引)