ES6 迭代器
es6 用的太少,每次看到陌生的东西就会从心底生出一种恐惧感,其实多翻翻文档,平时空的时候查阅下功能,偶尔使用使用就能想起来,也会减少内心的恐惧感,这偏文章仅限于个人记录
Iterator
Iterator 是 ES6 引入的一种新的遍历机制,迭代器有两个核心概念:
迭代器是一个统一的接口,它的作用是使各种数据结构可被便捷的访问,它是通过一个键为Symbol.iterator的方法来实现。
迭代器是用于遍历数据结构元素的指针(如数据库中的游标)。
const items = ["zero", "one", "two"];
const it = items[Symbol.iterator]();
it.next();
>{value: "zero", done: false}
it.next();
>{value: "one", done: false}
it.next();
>{value: "two", done: false}
it.next();
>{value: undefined, done: true}
上面的例子,首先创建一个数组,然后通过 Symbol.iterator 方法创建一个迭代器,之后不断的调用 next 方法对数组内部项进行访问,当属性 done 为 true 时访问结束。
迭代器是协议(使用它们的规则)的一部分,用于迭代。该协议的一个关键特性就是它是顺序的:迭代器一次返回一个值。这意味着如果可迭代数据结构是非线性的(例如树),迭代将会使其线性化。
ES6 规定,一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”。Symbol.iterator属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。
只要部署了遍历器接口就可以使用for…of遍历。
class RangeIterator {
constructor(start, stop) {
this.value = start;
this.stop = stop;
}
// 添加遍历器功能
[Symbol.iterator]() { return this; }
// 遍历器next方法的回调
next() {
var value = this.value;
if (value < this.stop) {
this.value++;
return {done: false, value: value};
}
return {done: true, value: undefined};
}
}
function range(start, stop) {
return new RangeIterator(start, stop);
}
for (var value of range(0, 3)) {
console.log(value); // 0, 1, 2
}
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'
}
以下场景会调用 Iterator 接口
let [test, ...rest] = [1,2,3] // 解构赋值
[...'hello'] // 扩展运算符
let generator1 = function* () {
yield* [1,2,3] // yield*
};
// for...of
// Array.from()
// Map(), Set(), WeakMap(), WeakSet()(比如new Map([['a',1],['b',2]]))
// Promise.all() Promise.race()