红宝书第十五讲:详解JavaScript迭代器与生成器:Symbol.iterator与yield
红宝书第十五讲:详解JavaScript迭代器与生成器:Symbol.iterator与yield
资料取自《JavaScript高级程序设计(第5版)》。
查看总目录:红宝书学习大纲
一、迭代器(Iterator)的“传送带”模式
迭代器像一个可暂停的传送带,逐项提供数据。任何对象实现 Symbol.iterator 方法即可成为可迭代对象,供 for...of 等遍历 [1]。
示例:手动控制数组迭代器
const colors = ['红', '绿', '蓝'];
const iterator = colors[Symbol.iterator](); // 获取迭代器工厂方法
console.log(iterator.next()); // { value: '红', done: false }
console.log(iterator.next()); // { value: '绿', done: false }
console.log(iterator.next()); // { value: '蓝', done: false }
console.log(iterator.next()); // { value: undefined, done: true }
[2]: 参考资料3说明可迭代对象必须通过 Symbol.iterator 实现迭代器接口
二、生成器(Generator)的“分步执行”特性
生成器使用 function* 声明,通过 yield 暂停执行并返回中间值,调用 next() 恢复执行 [1:1]。
示例:生成计数序列
function* countGenerator(max) {
let num = 0;
while (num < max) {
yield num++; // 暂停并返回值
}
}
const counter = countGenerator(3);
console.log(counter.next()); // { value: 0, done: false }
console.log(counter.next()); // { value: 1, done: false }
console.log(counter.next()); // { value: 2, done: false }
console.log(counter.next()); // { value: undefined, done: true }
[1:2]: 参考资料4展示yield如何中断生成器执行
flowchart LR
Start[生成器函数调用] --> 初始化状态
初始化状态 -- next()触发 --> 执行到yield
执行到yield --> 返回value并暂停
暂停状态 -- next()恢复 --> 继续执行
继续执行 -- 无yield --> 返回done:true
三、结合Symbol.iterator与生成器
用生成器简化自定义对象的迭代实现。只需在 Symbol.iterator 方法中定义 yield 序列 [1:3]。
示例:自定义范围生成器类
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
*[Symbol.iterator]() { // 生成器方法定义迭代规则
let current = this.start;
while (current <= this.end) {
yield current++;
}
}
}
const myRange = new Range(5, 7);
for (const num of myRange) {
console.log(num); // 依次输出5, 6, 7
}
[1:4]: 参考资料5示例类如何通过生成器方法变为可迭代对象
四、关键点对比
| 机制 | 迭代器 | 生成器 |
|---|---|---|
| 实现方式 | 手动定义 next() 方法 |
使用 function* 和 yield |
| 使用场景 | 明确控制每步流程 | 简化异步逻辑或复杂遍历步骤 |
| 语法复杂度 | 需要完整定义对象和方法 | 函数内部用 yield 简洁管理流程 |
应用场景
目录:总目录
上篇文章:红宝书第十四讲:详解JavaScript集合类型:Map、Set、WeakMap
脚注
《JavaScript高级程序设计(第5版)》示例类如何通过生成器方法变为可迭代对象。 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
《JavaScript高级程序设计(第5版)》展示yield如何中断生成器执行。 ↩︎
《JavaScript高级程序设计(第5版)》说明可迭代对象必须通过
Symbol.iterator实现迭代器接口。 ↩︎

浙公网安备 33010602011771号