ES6 Iterator 和 for of

一、Iterator:迭代器

迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象。结果对象有两个属性:一个是value,表示下一个将要返回的值;另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true。迭代器还会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用的值。

具有 Iterator 接口的数据结构:

  • Array / 类数组
  • String
  • Set 集合
  • Map 集合

Iterator 迭代器的原理:
默认的 Iterator 接口部署在数据结构的 Symbol.iterator 属性,一个数据结构只要具有 Symbol.iterator 属性,就是可迭代的。

二、Generator:生成器

生成器是一种返回迭代器的函数,通过function关键字后的星号(*)来表示,函数中会用到新的关键字yieldyield关键字也是ES6的新特性,可以通过它来指定调用迭代器的next()方法时的返回值及返回顺序

function* createIterator(array) {
  for (let i = 0; i < array.length; i++) {
    yield  array[i]
  }
}

let iterator = createIterator([1, 2, 3])

console.log(iterator.next())    //  { value: 1, done: false }
console.log(iterator.next())    //  { value: 2, done: false }
console.log(iterator.next())    //  { value: 3, done: false }
console.log(iterator.next())    //  { value: undefined, done: true }

生成器函数的一个特点是,当执行完一句 yield 语句后函数会自动停止执行,再次调用迭代器的 next() 方法才会继续执行下一个 yield 语句。
async/await 语法糖便是采用了这种方法。

yield关键字只可在生成器内部使用,在其他地方使用会报错;
不能用箭头函数来创建生成器。

三、可迭代对象和 for-of 循环

for-of用来循环遍历可迭代对象,for-of循环內部调用的就是数据结构的Symbol.iterator方法。

const array = [1, 2, 3]
for (const item of array) {
  console.log(item)
}
//  1
//  2
//  3

对于使用for-of的可迭代对象,for-of每执行一次就会调用这个可迭代对象的 next(),并将返回结果存储在一个变量中,持续执行直到可迭代对象 done 属性值为 false

非迭代对象使用 for of 循环需要对其添加 Symbol.iterator 属性:

const obj = {a: 1, b: 2, c: 3}

obj[Symbol.iterator] = function () {
  let i = 0
  const keys = Object.keys(this)
  return {
    next: () => {
      return i <= keys.length - 1 ? 
        {value: this[keys[i++]], done: false} : 
        {value: undefined, done: true}
    }
  }
}

for (let item of obj) {
  console.log(item)
}
//  1
//  2
//  3
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容