yield 用于委托迭代,将控制权交予可迭代对象逐个产出值,不缓冲不转换;要求目标实现[symbol.iterator],如数组、set等,不可直接用于普通对象;递归展开嵌套数组需类型判断;注意字符串和null/undefined边界;yield 表达式返回被委托迭代器的return值。

用 yield* 展开嵌套迭代器,核心是让当前生成器把控制权“交出去”,由被委托的可迭代对象逐个产出值,而不是自己手动循环或递归 yield。
yield* 的本质是迭代委托
它不是调用函数,也不是展开数组字面量,而是启动另一个迭代过程,并把它的每次产出原样透传给当前生成器的调用者。整个过程像流水线接驳,中间不缓冲、不聚合、不转换类型。
- 被委托对象必须实现
[Symbol.iterator]()方法(即为可迭代对象) - 常见合法目标:数组、字符串、Map、Set、Generator 函数调用结果、自定义迭代器
- 普通对象(如
{a:1})默认不可迭代,直接yield* {a:1}会报TypeError
递归展开嵌套数组的典型写法
对每一项判断是否为数组,是则用 yield* 委托自身;否则直接 yield 当前值:
function* flatten(arr) {
for (const item of arr) {
if (Array.isArray(item)) {
yield* flatten(item);
} else {
yield item;
}
}
}
<p>// 使用
const nested = [1, [2, 3], [4, [5, 6]], 7];
console.log([...flatten(nested)]); // [1, 2, 3, 4, 5, 6, 7]
</p>
注意字符串和类数组的边界情况
字符串也是可迭代对象,但通常你不希望把它拆成单个字符。所以实际使用中常加类型排除:
- 在 JavaScript 中,可用
typeof item === 'string'或item instanceof String判断后跳过 - 若需统一处理所有类数组(如
arguments,NodeList),可先转为真数组:Array.from(item)再yield* - 避免
yield* item直接作用于null或undefined,应提前校验
yield* 表达式本身有返回值
当被委托的迭代器执行完并调用 return(value) 时,该 value 就成为 yield* 表达式的值。这在需要收尾反馈的场景中有用:
function* gen1() {
yield 1;
yield 2;
return "done";
}
<p>function<em> gen2() {
const result = yield</em> gen1(); // result === "done"
yield <code>finished with ${result}</code>;
}
</p>










