x-note
Search…
ECMAScript 6 Iterator
ES6 里的Iterator并不是一种新的语法或是新的内置对象,而是一种协议(protocl),所有遵循了这个协议的对象都可以称之为“迭代器对象”。
ES6 规定,默认的 Iterator 接口需要部署在数据结构的Symbol.iterator属性上 —— iterable protocol (可迭代协议),也就是说,对象必须包含Symbol.iterator方法。此外,并且该方法返回一个符合 iterator protocol(迭代器协议)规定的对象 。该对象包含 1 个next()方法,该方法返回一个对象 ,对象包含以下两个属性:
  • value —— 值
  • done —— 布尔值,标记是否结束遍历
1
let obj = {
2
[Symbol.iterator]: function* () {
3
yield 1;
4
yield 2;
5
}
6
}
7
[...obj] // [1, 2]
Copied!
原生具备 Iterator 接口的数据结构如下:
  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

默认使用 Iterator 的场景

for...of语句
1
for (let v of [1, 2, 3, 4]) {
2
if (v === 1) {
3
continue;
4
} else if (v === 4) {
5
break;
6
}
7
console.log(v);
8
}
9
// 2 3
Copied!
解构赋值
对数组和 Set 进行解构赋值时,会默认使用 Iterator
1
let set = new Set().add('a').add('b').add('c');
2
let [a, b] = set;
3
// a = 'a'
4
// b = 'b'
5
let [first, ...rest] = set;
6
// first = 'a'
7
// rest = ['b', 'c']
Copied!
扩展运算符(...)
扩展运算符(...)也会调用默认的 Iterator 接口。
1
function fn (x, y, z) {
2
console.log(x, y, z);
3
}
4
let arr = [1, 2, 3];
5
fn(...arr); // 1 2 3
Copied!
yield*语法
yield*后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口
1
let generator = function* () {
2
yield 1;
3
yield* [2, 3];
4
yield 4;
5
};
6
7
var iterator = generator();
8
9
iterator.next() // { value: 1, done: false }
10
iterator.next() // { value: 2, done: false }
11
iterator.next() // { value: 3, done: false }
12
iterator.next() // { value: 4, done: false }
13
iterator.next() // { value: undefined, done: true }
Copied!
遍历数组
数组的遍历会调用遍历器接口,所以任何接受数组作为参数的场合,其实都调用了遍历器接口。