红宝书第十五讲:详解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

示例:生成计数序列
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: 参考资料4展示yield如何中断生成器执行

flowchart LR
    Start[生成器函数调用] --> 初始化状态
    初始化状态 -- next()触发 --> 执行到yield
    执行到yield --> 返回value并暂停
    暂停状态 -- next()恢复 --> 继续执行
    继续执行 -- 无yield --> 返回done:true

三、结合Symbol.iterator与生成器

用生成器简化自定义对象的迭代实现。只需在 Symbol.iterator 方法中定义 yield 序列 1

示例:自定义范围生成器类
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: 参考资料5示例类如何通过生成器方法变为可迭代对象


四、关键点对比

机制迭代器生成器
实现方式手动定义 next() 方法使用 function*yield
使用场景明确控制每步流程简化异步逻辑或复杂遍历步骤
语法复杂度需要完整定义对象和方法函数内部用 yield 简洁管理流程

应用场景

  1. 自定义数据结构遍历(如树、链表) 1
  2. 按需生成大数据集(避免一次性加载内存爆满)
  3. 结合异步操作(配合 async/await 处理延迟数据)3

目录:总目录
上篇文章:红宝书第十四讲:详解JavaScript集合类型:Map、Set、WeakMap

下篇文章:红宝书第十六讲:通俗详解JavaScript回调函数与事件循环

脚注


  1. 《JavaScript高级程序设计(第5版)》示例类如何通过生成器方法变为可迭代对象。
  2. 《JavaScript高级程序设计(第5版)》展示yield如何中断生成器执行。
  3. 《JavaScript高级程序设计(第5版)》说明可迭代对象必须通过 Symbol.iterator 实现迭代器接口。

kovli
10 声望4 粉丝