迭代器

在javascript中,迭代器是一个对象,它定义一个序列,并在终止时可能返回一个值。
具体的说,迭代器通过next() 方法,实现迭代协议的任何一个对象,该方法返回一句具有
value 属性 和done属性 ,这个两个属性的一个对象,如果迭代完成则done为true,如果value和done
一起存在,则是迭代器的返回值。

一旦创建,迭代对象可以通过重复调用next()方法显示迭代,迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。 在产生终止值之后,对next()的额外调用应该继续返回{done:true}。

Javascript中最常见的迭代器是Array迭代器,它只是按顺序返回关联数组中的每个值。 虽然很容易想象所有迭代器都可以表示为数组,但事实并非如此。 数组必须完整分配,但迭代器仅在必要时使用,因此可以表示无限大小的序列,例如0和无穷大之间的整数范围。

  1. function createIterator(items) {
  2. var i = 0;
  3. return {
  4. next: function() {
  5. var done = (i >= items.length);
  6. var value = !done ? items[i++] : undefined;
  7. return {
  8. done: done,
  9. value: value
  10. };
  11. }
  12. };
  13. }
  14. var iterator = createIterator([1, 2, 3]);
  15. console.log(iterator.next());
  16. console.log(iterator.next());

生成器

虽然自定义的迭代器是一个有用的工具,但由于需要显式地维护其内部状态,因此需要谨慎地创建。
生成器函数提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。生成器函数使用function * 语法编写。 最初调用时,生成器函数不执行任何代码,而是返回一种称为Generator的迭代器。通过调用生成器的下一个方法消耗值时,Generator函数将执行,直到遇到yield关键字。

可迭代协议

可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为,例如,在一个 for..of 结构中,哪些值可以被遍历到。一些内置类型同时是内置可迭代对象,并且有默认的迭代行为,比如 Array 或者 Map,而其他内置类型则不是(比如 Object))

要成为可迭代对象, 一个对象必须实现 **@@iterator** 方法。这意味着对象(或者它原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator 访问该属性:

当一个对象需要被迭代的时候(比如被置入一个 for...of 循环时),首先,会不带参数调用它的 @@iterator 方法,然后使用此方法返回的迭代器获得要迭代的值。

迭代器协议

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。
只有实现了一个拥有以下语义(semantic)的 **next()** 方法,一个对象才能成为迭代器:

生成器对象到底是一个迭代器,还是一个可迭代对象?

既是迭代器,也是可迭代对象