全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-16 8 分钟 ✍️ juanwangdev

JavaScript 生成器与迭代器

生成器是可暂停的函数,迭代器是遍历数据的协议,两者配合实现惰性求值。

迭代器协议

迭代器需实现 next() 方法,返回 { value, done }

JavaScript
function createIterator(arr) {
  let index = 0;
  return {
    next() {
      if (index < arr.length) {
        return { value: arr[index++], done: false };
      }
      return { value: undefined, done: true };
    }
  };
}

const it = createIterator([1, 2, 3]);
it.next();  // { value: 1, done: false }
it.next();  // { value: 2, done: false }
it.next();  // { value: 3, done: false }
it.next();  // { value: undefined, done: true }

可迭代协议

对象需实现 [Symbol.iterator]() 方法,返回迭代器:

JavaScript
const iterable = {
  data: [1, 2, 3],
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => {
        if (index < this.data.length) {
          return { value: this.data[index++], done: false };
        }
        return { done: true };
      }
    };
  }
};

// 可用于 for...of
for (const item of iterable) {
  console.log(item);  // 1, 2, 3
}

生成器函数

使用 function* 定义,yield 暂停执行:

JavaScript
function* generator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = generator();
gen.next();  // { value: 1, done: false }
gen.next();  // { value: 2, done: false }
gen.next();  // { value: 3, done: false }
gen.next();  // { value: undefined, done: true }

yield 表达式

yield 接收值

JavaScript
function* chat() {
  const name = yield 'What is your name?';
  return `Hello, ${name}!`;
}

const gen = chat();
gen.next();           // { value: 'What is your name?', done: false }
gen.next('Alice');    // { value: 'Hello, Alice!', done: true }

yield* 委托

JavaScript
function* gen1() {
  yield 1;
  yield 2;
}

function* gen2() {
  yield* gen1();
  yield 3;
}

[...gen2()];  // [1, 2, 3]

生成器实现异步

JavaScript
function* fetchUser() {
  const user = yield fetch('/api/user');
  const posts = yield fetch(`/api/posts/${user.id}`);
  return posts;
}

// 执行器
function runGenerator(gen) {
  const iterator = gen();
  function handle(result) {
    if (result.done) return result.value;
    return result.value.then(data => handle(iterator.next(data)));
  }
  return handle(iterator.next());
}

实际应用

惰性序列

JavaScript
function* range(start, end, step = 1) {
  for (let i = start; i < end; i += step) {
    yield i;
  }
}

[...range(0, 10, 2)];  // [0, 2, 4, 6, 8]

无限序列

JavaScript
function* fibonacci() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();
fib.next().value;  // 0
fib.next().value;  // 1
fib.next().value;  // 1
fib.next().value;  // 2

自定义迭代

JavaScript
class Tree {
  constructor(value, left = null, right = null) {
    this.value = value;
    this.left = left;
    this.right = right;
  }

  *[Symbol.iterator]() {
    yield this.value;
    if (this.left) yield* this.left;
    if (this.right) yield* this.right;
  }
}

const tree = new Tree(1,
  new Tree(2),
  new Tree(3)
);
[...tree];  // [1, 2, 3]

内置可迭代对象

对象迭代方式
Arrayfor...of, ... 展开
String逐字符迭代
Map[key, value] 键值对
Set元素值
arguments函数参数

要点总结

  • 迭代器实现 next() 返回 { value, done }
  • 可迭代对象实现 [Symbol.iterator] 方法
  • 生成器 function* + yield 实现惰性求值
  • yield* 委托给其他生成器
  • 生成器可配合 Promise 实现异步流程控制

📝 发现内容有误?点击此处直接编辑

← 上一篇 JavaScript 模块化(ES Modules)
下一篇 → JavaScript 闭包
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库