Appearance
Iterator(遍历器)
为各种数据结构,提供一个统一的、简便的访问接口;(统一)
是使得数据结构的成员能够按某种次序排列;(按序)
是 ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费。
原生具备 Iterator 接口的数据结构如下
- Array
- Map
- Set
- String
- TypedArray
- 函数的 arguments 对象
- NodeList 对象
计算生成的
- entries() 返回一个遍历器对象,用来遍历[键名, 键值]组成的数组。对于数组,键名就是索引值;对于 Set,键名与键值相同。Map 结构的 Iterator 接口,默认就是调用 entries 方法。
- keys() 返回一个遍历器对象,用来遍历所有的键名。
- values() 返回一个遍历器对象,用来遍历所有的键值
例子
- Array
js
Array.prototype._protoKey = function() {
console.log('Array_protoKey');
};
let arr = [1, 2, 3, 4, 5];
// for
console.log('--------of-------------');
for (var item of arr) {
console.log(`${item}`); // 1,2,3,4,5
}
- Map
js
let map = new Map();
map.set({ a: 1 }, 'content');
map.set({ a: 2 }, 'content2');
map.set(3, 'content2');
// for
for (var item of map) {
console.log(`${item}`);
}
// 结果为:
// [object Object],content
// [object Object],content2
// 3,content2
- Set
js
let set = new Set();
set.add({ a: 1 });
set.add({ a: 1 });
set.add(3);
set.add(3);
set.add(4);
// for
for (var item of set) {
console.log(`${item}`);
}
// 结果为:
// [object Object]
// [object Object]
// 3
// 4
默认调用 Iterator 接口的场合
- 解构赋值
在对数组和 Set 进行结构赋值的时候就是调用的Symbol.iterator
js
let 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'];
扩展运算符
yield*
yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。
js
let generator = function*() {
yield 1;
yield* [2, 3, 4];
yield 5;
};
var iterator = generator();
iterator.next(); // { value: 1, done: false }
iterator.next(); // { value: 2, done: false }
iterator.next(); // { value: 3, done: false }
iterator.next(); // { value: 4, done: false }
iterator.next(); // { value: 5, done: false }
iterator.next(); // { value: undefined, done: true }
- 其他场合
由于数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。下面是一些例子。
- for...of
- Array.from()
- Map(), Set(), WeakMap(), WeakSet()(比如 new Map([['a',1],['b',2]]))
- Promise.all()
- Promise.race()
类数组
类数组(没有 Inteador,所有不能使用 for of)
js
let likeArr = {
0: 'gz0',
1: 'gz1',
2: 'gz2',
3: 'gz3',
4: 'gz4',
length: 5,
};
for (var item of likeArr) {
// likeArr is not iterable
console.log(`${item}`);
}
我们可以改造
js
let 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'
}
第二种方式
js
let iterable = {
0: 'a',
1: 'b',
2: 'c',
length: 3,
};
iterable = Array.from(iterable); //装换成数组
for (let item of iterable) {
console.log(item); // 'a', 'b', 'c'
}