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

JavaScript 中的 yield 关键字本身不“工作”,它只在 function*(生成器函数)内部起作用,且必须配合迭代器协议才能产生实际效果。
生成器函数返回的是迭代器对象,不是执行结果
调用 function* 不会立即运行函数体,而是返回一个实现了 next() 方法的迭代器对象。每次调用 iterator.next(),函数才从上次暂停处继续执行,直到下一个 yield 或 return。
-
yield表达式会暂停执行,并把右侧值作为{ value: ..., done: false }的value返回 - 再次调用
next()时,函数从yield后恢复,上一次yield表达式的返回值是本次next(arg)传入的arg - 函数结束或遇到
return时,done变为true,value是返回值(或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...of或next().then() -
yield后面可以是任意表达式,包括yield* anotherGenerator()(委托迭代)
迭代器协议是底层契约,for...of 和展开运算符依赖它
for...of、[...iter]、Array.from(iter) 等语法糖,本质都是反复调用 iter.next(),直到 done: true。如果对象没有 [Symbol.iterator]() 方法,就会报错 TypeError: XXX is not iterable。
立即学习“Java免费学习笔记(深入)”;
- 生成器函数自动实现
[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...finally 在 return 或 throw 时仍会执行,但 yield 暂停期间不会触发;另外,yield 表达式本身有返回值,这个值只在下一次 next(arg) 时传入,不是 yield 右侧表达式的值。










