此頁面由社群從英文翻譯而來。了解更多並加入 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 關鍵字後面跟著一個星號)定義了一個生成器函式(generator function),他會回傳一個生成器(Generator)物件。
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你可以透過GeneratorFunction 建構式來定義生成器函式。
語法
function* name([param[, param[, ... param]]]) { statements}name函式名稱。
param要被傳入函式的引數名稱,一個函式最多可以擁有 255 個引數。
statementsstatements 構成了函式內容的陳述式。
描述
生成器是可以離開後再次進入的函式。在兩次進入之間,生成器的執行狀態(變數綁定狀態)會被儲存。
呼叫生成器函式並不會讓裡面的程式碼立即執行,而是會回傳一個針對該函式的迭代器(iterator)物件。當呼叫迭代器的next() 方法時,生成器函式將會執行到遭遇的第一個yield 運算式,該運算式給定的值將從迭代器中回傳,如果是yield* 則會交給另一個生成器函式處理。next() 方法回傳一個物件,該物件有value 屬性,包含了產生的數值,還有done 屬性,為布林值,指出該生成器是否產出最後的數值。呼叫next() 方法如果帶有一個參數,將會讓先前暫停的生成器函式恢復執行,以該參數值取代先前暫停的yield 陳述式。
生成器中的return 陳述式被執行時,會讓生成器done 狀態為真。若有數值被返回的動作帶回,將是放在value 傳回的。已返回的生成器不會再產生任何數值。
範例
>簡單例子
function* idMaker() { var index = 0; while (index < index + 1) yield index++;}var 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;}var 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);}var gen = logGenerator();// the first call of next executes from the start of the function// until the first yield statementgen.next(); // 0gen.next("pretzel"); // 1 pretzelgen.next("california"); // 2 californiagen.next("mayonnaise"); // 3 mayonnaise生成器中的回傳陳述式
function* yieldAndReturn() { yield "Y"; return "R"; yield "unreachable";}var gen = yieldAndReturn();console.log(gen.next()); // { value: "Y", done: false }console.log(gen.next()); // { value: "R", done: true }console.log(gen.next()); // { value: undefined, done: true }生成器無法被建構
function* f() {}var 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}規範
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-generator-function-definitions> |
瀏覽器相容性
Firefox 規範註記
Generators and iterators in Firefox versions before 26
Older Firefox versions implement an older version of the generators proposal. In the older version, generators were defined using a regularfunction keyword (without an asterisk) among other differences. SeeLegacy generator function for further information.
IteratorResult object returned instead of throwing
Starting with Gecko 29, the completed generator function no longer throws aTypeError "generator has already finished". Instead, it returns anIteratorResult object like{ value: undefined, done: true } (Firefox bug 958951).
參見
function* expressionGeneratorFunctionobject- 迭代協議
yieldyield*Functionobjectfunction declarationfunction expressionFunctions and function scope- Other web resources:
- Regenerator an ES2015 generator compiler to ES5
- Forbes Lindesay: Promises and Generators: control flow utopia — JSConf EU 2013
- Task.js
- Iterating generators asynchronously