此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
function*
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2016年9月.
function* 声明创建一个绑定到给定名称的新生成器函数。生成器函数可以退出,并在稍后重新进入,其上下文(变量绑定)会在重新进入时保存。
你也可以使用function* 表达式来定义生成器函数。
In this article
尝试一下
function* generator(i) { yield i; yield i + 10;}const gen = generator(10);console.log(gen.next().value);// Expected output: 10console.log(gen.next().value);// Expected output: 20语法
function* name(param0) { statements}function* name(param0, param1) { statements}function* name(param0, param1, /* …, */ paramN) { statements}备注:箭头函数不能用来定义生成器函数。
备注:function 和* 是两个单独的标记,因此它们可以用空白或换行符分隔。
参数
name函数名称。
param可选函数的形参名称。有关参数的语法,请参阅函数参考。
statements可选构成函数体的语句。
描述
function* 声明创建一个GeneratorFunction 对象。每次调用生成器函数时,它都会返回一个新的Generator 对象,该对象符合迭代器协议。当迭代器的next() 方法被调用时,生成器函数的主体会被执行,直到遇到第一个yield 表达式,该表达式指定了迭代器要返回的值,或者用yield* 委托给另一个生成器函数。next() 方法返回一个对象,其value 属性包含了yield 表达式的值,done 属性是布尔类型,表示生成器是否已经返回了最后一个值。如果next() 方法带有参数,那么它会恢复生成器函数的执行,并用参数替换暂停执行的yield 表达式。
在 JavaScript 中,生成器——尤其是与 Promises 结合使用时——是一种非常强大的异步编程工具,它们解决了回调函数存在的一些的问题,如回调地狱和控制反转。然而,通过使用异步函数,我们可以更简单地解决这些问题。
在生成器中执行return 语句会使生成器结束(即返回的对象的done 属性将被设置为true)。如果返回一个值,它将被设置为生成器返回的对象的value 属性。与return 语句类似,如果生成器内部抛出错误,生成器也会结束,除非在生成器的代码体内捕获该错误。当生成器结束后,后续next() 调用不会执行生成器的任何代码,只会返回一个形如{value: undefined, done: true} 的对象。
function* 声明的行为与function 声明类似——它们会被提升到其作用域的顶部,并且可以在当前作用域的任何位置被调用,且只能在特定的上下文中被重新声明。
示例
>简单示例
function* idMaker() { let index = 0; while (true) { yield index++; }}const gen = idMaker();console.log(gen.next().value); // 0console.log(gen.next().value); // 1console.log(gen.next().value); // 2console.log(gen.next().value); // 3// …使用 yield* 示例
function* anotherGenerator(i) { yield i + 1; yield i + 2; yield i + 3;}function* generator(i) { yield i; yield* anotherGenerator(i); yield i + 10;}const gen = generator(10);console.log(gen.next().value); // 10console.log(gen.next().value); // 11console.log(gen.next().value); // 12console.log(gen.next().value); // 13console.log(gen.next().value); // 20传入参数给生成器
function* logGenerator() { console.log(0); console.log(1, yield); console.log(2, yield); console.log(3, yield);}const gen = logGenerator();// next 的第一次调用从函数的开头开始执行,直到第一个 yield 语句gen.next(); // 0gen.next("pretzel"); // 1 pretzelgen.next("california"); // 2 californiagen.next("mayonnaise"); // 3 mayonnaise生成器中的返回语句
function* yieldAndReturn() { yield "产生的值"; return "返回的值"; yield "不会被访问到的值";}const gen = yieldAndReturn();console.log(gen.next()); // { value: "产生的值", done: false }console.log(gen.next()); // { value: "返回的值", done: true }console.log(gen.next()); // { value: undefined, done: true }生成器作为对象属性
const someObj = { *generator() { yield "a"; yield "b"; },};const gen = someObj.generator();console.log(gen.next()); // { value: 'a', done: false }console.log(gen.next()); // { value: 'b', done: false }console.log(gen.next()); // { value: undefined, done: true }生成器作为对象方法
class Foo { *generator() { yield 1; yield 2; yield 3; }}const f = new Foo();const gen = f.generator();console.log(gen.next()); // { value: 1, done: false }console.log(gen.next()); // { value: 2, done: false }console.log(gen.next()); // { value: 3, done: false }console.log(gen.next()); // { value: undefined, done: true }生成器作为计算属性
class Foo { *[Symbol.iterator]() { yield 1; yield 2; }}const SomeObj = { *[Symbol.iterator]() { yield "a"; yield "b"; },};console.log(Array.from(new Foo())); // [ 1, 2 ]console.log(Array.from(SomeObj)); // [ 'a', 'b' ]生成器是不可构造的
function* f() {}const obj = new f(); // throws "TypeError: f is not a constructor使用表达式定义生成器
const foo = function* () { yield 10; yield 20;};const bar = foo();console.log(bar.next()); // {value: 10, done: false}生成器示例
function* powers(n) { // 无限循环生成 for (let current = n; ; current *= n) { yield current; }}for (const power of powers(2)) { // 控制生成器 if (power > 32) { break; } console.log(power); // 2 // 4 // 8 // 16 // 32}规范
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-generator-function-definitions> |
浏览器兼容性
参见
- 函数指南
- 迭代器与生成器指南
- 函数
GeneratorFunctionfunction*表达式functionasync functionasync function*- 迭代协议
yieldyield*Generator- GitHub 上的Regenerator
- Promise 和生成器:控制流的乌托邦——Forbes Lindesay 在 JSConf 上的演讲(2013)
- GitHub 上的Task.js
- 你不知道的 JS:异步和性能,第 4 章:生成器——Kyle Simpson