返回文章列表
frontend2026年3月17日1 分钟阅读

迭代器

迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值,类似遍历数组打印。 在 JS 中,迭代器是一个实现了特定接口的对象。任何对象只要包含 [Symbol.iterator] 属性,且该属性是一个返回迭代器对象的函数,它就是“可迭代的”。 迭代器对象必须包含一个 next() 方法,每次调用返回如下结构: { value: 任何值, done: 布尔值 }

自定义迭代器的实现

采用闭包来实现一个简单的迭代器,当超过当前迭代限制时,返回一个新的迭代器

class MyIterator { constructor(limit) { this.limit = limit; } // 部署可迭代接口 [Symbol.iterator]() { let count = 0; // 使用箭头函数,确保内部的 this 穿透指向 MyIterator 实例 return { next: () => { if (count < this.limit) { return { value: count++, done: false }; } else { return { value: undefined, done: true }; } }, // 迭代器也可以通过 return 方法提前结束(比如在 for...of 中 break) return: () => { console.log('迭代被提前终止'); return { done: true }; } }; } } const myIter = new MyIterator(3); for (const val of myIter) { console.log(val); // 依次打印: 0, 1, 2 }

迭代器的应用

  • 展开运算符:[...myIter] 会自动调用迭代器消费所有值。
  • 解构赋值:const [a, b] = myIter。
  • 原生数据结构:Array、Map、Set、String、NodeList 默认都实现了迭代器接口。

生成器

ES6新增的一个特性「可以在一个函数块内暂停和恢复代码执行」,生成器可以通过yield关键字来暂停函数的执行, 因为生成器对象实际上也实现了 iterator 接口,所以可以通过next方法来恢复函数的执行,生成器函数会返回一个迭代器对象。

生成器的实现

调用生成器函数不会立刻执行代码,而是返回一个生成器对象,一个比较简单的示例如下

function* myGenerator(){ yield 1 yield 2 yield 3 } const gen = myGenerator() console.log(gen.next()) // {value: 1, done: false} console.log(gen.next()) // {value: 2, done: false} console.log(gen.next()) // {value: 3, done: false} console.log(gen.next()) // {value: undefined, done: true}

生成器的双向通信(协程基础)

生成器最强大的地方在于:它不仅能向外 yield(产出)值,外部还能通过 next(参数) 向生成器内部注入值。 「控制权可以在多个代码块之间来回交替,并且可以互相传递数据。」

function* chatGenerator() { const question = yield "你好!你叫什么名字?"; // 暂停并传出字符串 yield `原来是 ${question} 呀,很高兴认识你!`; // 接收外部传进来的值并再次传出 } const chat = chatGenerator(); console.log(chat.next().value); // 输出: "你好!你叫什么名字?" console.log(chat.next("前端小明").value); // 输出: "原来是 前端小明 呀,很高兴认识你!"

生成器的应用

虽然日常业务中我们更常写 async/await,但 async/await 本质上就是 生成器 (Generator) + Promise 的语法糖。 Babel 编译低版本代码时,就是用 Generator 模拟 async 的。 在处理复杂状态机、或者前端复杂异步流控制(如状态管理库 Redux-Saga)时,Generator 依然是不可替代的利器。

今天就先到这里,关于协程的内容会在学习之后进行总结和补充

© 2026 Blog Owner. All rights reserved.