1. 迭代器是啥

迭代器(iterator)为可以对数组或集合进行遍历的工具。只有实现了迭代器工厂函数的数据类型才能使用Iterable接口:

  • 字符串(StringIterator)
  • 数组(ArrayIterator)
  • 映射(MapIterator)
  • 集合(SetIterator)
  • arguments对象(ArrayIterator)
  • NodeList等DOM集合类型(ArrayIterator)

并且迭代器与可迭代对象的属性是同步的,如果可迭代对象在迭代期间被修改了,那么迭代器会反映相应的变化。迭代器维护着一个可迭代对象的引用,会阻止垃圾回收程序回收可迭代对象。


2. 自定义迭代器

class Counter { 
   constructor(limit) { 
      this.limit = limit; 
   } 
 [Symbol.iterator]() { 
    let count = 1, 
    limit = this.limit; 
    return { 
       next() { 
          if (count <= limit) { 
             return { done: false, value: count++ }; 
          } else { 
             return { done: true, value: undefined }; 
          } 
   } 
 }; 
 } 
} 
let counter = new Counter(3); 
for (let i of counter) { console.log(i); } 
// 1 
// 2 
// 3 
for (let i of counter) { console.log(i); } 
// 1 
// 2 
// 3

以上为闭包实现的自定义可迭代器,以这种方式创建的迭代器也实现了Iterable接口。Symbol.iterator属性引用的工厂函数会返回相同的迭代器


3. 提前终止迭代器

  • for-of循环通过break、continue、return或throw提前退出
  • 结构操作并未消费所有值

如果迭代器没有关闭,可以继续从上次离开的地方继续迭代。数组的迭代器不能关闭


4. 小结

迭代器是由任意对象实现的接口,支持连续获取对象产出的每个值。实现了Iterable接口的都有一个Symbol.iterator属性,引用默认迭代器,调用该函数会产生一个实现Iterator接口的对象。 迭代器必须通过next方法才能连续获取值,该方法返回一个IteratorObject,该对象包含done属性和value属性,done值表示是否还有值可以访问(true为迭代完成),value为迭代器返回的当前值。