javascript生成器是什么_yield关键字怎么用【教程】

生成器函数用function*声明,调用返回迭代器,需next()触发执行;yield暂停并交出控制权,可接收next传入值;return终止生成器;不可重用,非为替代循环而生。

JavaScript 生成器不是普通函数,它能暂停执行、交出控制权,并在后续恢复——yield 就是这个暂停和交出的指令。

生成器函数怎么声明和调用?

生成器函数必须用 f

unction* 声明(星号紧贴 function 关键字),调用后不立即执行,而是返回一个迭代器对象。

  • 错误写法:function myGen() { yield 1; } → 语法报错,缺少 *
  • 正确写法:function* myGen() { yield 1; yield 2; }
  • 调用后得到的是迭代器:const it = myGen();,此时函数体未运行
  • 真正触发执行要靠 it.next(),第一次调用才开始运行到第一个 yield

yield 返回什么?怎么接收传入值?

yield 表达式本身有返回值:它会把外部通过 next(value) 传入的 value 作为本次 yield 表达式的计算结果。

  • it.next()(无参)时,yield 表达式值为 undefined
  • it.next(42) 时,当前 yield 左边的变量会接收到 42,例如:const x = yield 1;x 变成 42
  • 每次 next() 返回形如 { value: ..., done: ... } 的对象,valueyield 后面的值(或 return 的值),done 表示是否结束

生成器里能用 return 吗?和 yield 有什么区别?

可以,但语义不同:return 表示生成器彻底结束,后续 next() 调用都返回 { value: undefined, done: true };而 yield 是暂停,还能继续。

  • yield 1; → 返回 { value: 1, done: false }
  • return 2; → 返回 { value: 2, done: true }
  • 如果生成器函数体结束没写 return,最后一步自动返回 { value: undefined, done: true }
  • throw()return() 方法也能强制结束生成器,但会跳过后续 yield

常见误用和性能注意点

生成器不是为替代循环而生的,它的核心价值在于“可中断的同步逻辑”或手动控制异步流程(比如早期 co 库)。滥用会导致可读性下降和意外状态。

  • 不要在箭头函数里用 function* —— 箭头函数不能是生成器
  • yield 只能在生成器函数内使用,嵌套普通函数里直接报 Uncaught SyntaxError: Unexpected identifier
  • 生成器对象不可重用:一旦 done: true,再次 next() 永远返回 { value: undefined, done: true }
  • V8 对生成器有优化,但大量短生命周期生成器(比如每次渲染都新建)可能比数组 map 慢,别为了“酷”硬套

最易被忽略的一点:生成器的“暂停点”只存在于 yield 表达式求值完成之后,不是语句开头;也就是说,yield foo() 会先执行 foo(),再暂停并返回其结果——这决定了副作用发生的时机。