simple's Studio.

ES6中的迭代器协议和可迭代协议

2017/11/04

在继续之前,我们先花些时间看一下 ES6 中的两个新协议:

  • 可迭代协议
  • 迭代器协议

这两个协议不是内置的,但是它们可以帮助你理解 ES6 中的新迭代概念,就像给你展示标识符的使用案例一样。

###可迭代协议
可迭代协议用来定义和自定义对象的迭代行为。也就是说在 ES6 中,你可以灵活地指定循环访问对象中的值的方式。对于某些对象,它们已经内置了这一行为。例如,字符串和数组就是内置可迭代类型的例子。

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
  console.log(digit);
}
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 

在前面的文章里提到,任何可迭代的对象都可以使用新的 for…of 循环。在这节课的稍后阶段,我们还将学习 Set(集合)和 Map(映射),它们也是内置可迭代类型。

###工作原理
为了使对象可迭代,它必须实现可迭代接口。如果你之前使用的是 Java 或 C 语言等语言,那么你可能熟悉接口,但是如果没用过这些语言,接口其实就是为了让对象可迭代,它必须包含默认的迭代器方法。该方法将定义对象如何被迭代。

迭代器方法(可通过常量 [Symbol.iterator] 获得)是一个无参数的函数,返回的是迭代器对象。迭代器对象是遵守迭代器协议的对象。

###迭代器协议
迭代器协议用来定义对象生成一系列值的标准方式。实际上就是现在有了定义对象如何迭代的流程。通过执行 .next() 方法来完成这一流程。

###工作原理
当对象执行 .next() 方法时,就变成了迭代器。.next() 方法是无参数函数,返回具有两个属性的对象:

value:表示对象内值序列的下个值的数据
done:表示迭代器是否已循环访问完值序列的布尔值
如果 done 为 true,则迭代器已到达值序列的末尾处。
如果 done 为 false,则迭代器能够生成值序列中的另一个值。
下面是之前的一个示例,但是我们改为使用数组的默认迭代器访问数组中的每个值。

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
const arrayIterator = digits[Symbol.iterator]();

console.log(arrayIterator.next());
console.log(arrayIterator.next());
console.log(arrayIterator.next());
Object {value: 0, done: false}
Object {value: 1, done: false}
Object {value: 2, done: false}
CATALOG