信息发布→ 登录 注册 退出

如何学习JavaScript中的迭代器与生成器_JavaScript的yield关键字如何工作

发布时间:2026-01-11

点击量:
yield仅在function生成器函数中有效,配合迭代器协议通过next()控制暂停/恢复执行,返回{value, done}对象;不可用于普通、箭头或async函数(除非async function);自动生成[Symbol.iterator],支持for...of等语法糖。

JavaScript 中的 yield 关键字本身不“工作”,它只在 function*(生成器函数)内部起作用,且必须配合迭代器协议才能产生实际效果。

生成器函数返回的是迭代器对象,不是执行结果

调用 function* 不会立即运行函数体,而是返回一个实现了 next() 方法的迭代器对象。每次调用 iterator.next(),函数才从上次暂停处继续执行,直到下一个 yieldreturn

  • yield 表达式会暂停执行,并把右侧值作为 { value: ..., done: false }value 返回
  • 再次调用 next() 时,函数从 yield 后恢复,上一次 yield 表达式的返回值是本次 next(arg) 传入的 arg
  • 函数结束或遇到 return 时,done 变为 truevalue 是返回值(或 undefined
function* countdown(n) {
  while (n > 0) {
    yield n;
    n--;
  }
  return 'done';
}

const iter = countdown(3); console.log(iter.next()); // { value: 3, done: false } console.log(iter.next()); // { value: 2, done: false } console.log(iter.next()); // { value: 1, done: false } console.log(iter.next()); // { value: 'done', done: true }

yield 不能出现在普通函数、箭头函数或异步函数中

语法错误会直接抛出 SyntaxError,比如在 async function 里写 yield,或在 () => { yield 1; } 中使用——这些都不合法。

  • 只有 function* 内部允许 yield
  • async function* 是合法的,它返回异步迭代器,yield 仍可用,但需配合 for await...ofnext().then()
  • yield 后面可以是任意表达式,包括 yield* anotherGenerator()(委托迭代)

迭代器协议是底层契约,for...of 和展开运算符依赖它

for...of[...iter]Array.from(iter) 等语法糖,本质都是反复调用 iter.next(),直到 done: true。如果对象没有 [Symbol.iterator]() 方法,就会报错 TypeError: XXX is not iterable

  • 生成器函数自动实现 [Symbol.iterator],所以可直接用于 for...of
  • 手动实现迭代器需返回带 next() 的对象,yield 是最简方式,否则要自己维护状态和 done 标志
  • 注意:生成器一旦 done: true,后续所有 next() 调用都返回 { value: undefined, done: true },不可重用
function* fib() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fibIter = fib(); console.log(fibIter.next().value); // 0 console.log(fibIter.next().value); // 1 console.log(fibIter.next().value); // 1 console.log(fibIter.next().value); // 2

// 可无限遍历(但注意别用 [...fib()],会卡死) for (const n of fib()) { if (n > 10) break; console.log(n); // 0 1 1 2 3 5 8 }

真正容易被忽略的是:生成器函数内部的 try...finallyreturnthrow 时仍会执行,但 yield 暂停期间不会触发;另外,yield 表达式本身有返回值,这个值只在下一次 next(arg) 时传入,不是 yield 右侧表达式的值。

标签:# javascript  # java  # ai  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!