function*

由於本文件沒有此語言的翻譯版本,您閱讀的是英文版的內容。 幫助我們翻譯這篇文章!

function* 宣告式(function 關鍵字後面跟著一個星號)定義了一個生成器函式(generator function),他會回傳一個生成器(Generator)物件。

你可以透過 GeneratorFunction 建構式來定義生成器函式。

語法

function* name([param[, param[, ... param]]]) {
   statements
}
name
函式名稱。
param
要被傳入函式的引數名稱,一個函式最多可以擁有 255 個引數。
statements
statements 構成了函式內容的陳述式。

描述

生成器是可以離開後再次進入的函式。在兩次進入之間,生成器的執行狀態(變數綁定狀態)會被儲存。

呼叫生成器函式並不會讓裡面的程式碼立即執行,而是會回傳一個針對該函式的迭代器(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); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.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); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.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 statement
gen.next();             // 0
gen.next('pretzel');    // 1 pretzel
gen.next('california'); // 2 california
gen.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 Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'function*' in that specification.
Standard Initial definition.
ECMAScript 2016 (ECMA-262)
The definition of 'function*' in that specification.
Standard Changed that generators should not have [[Construct]] trap and will throw when used with new.
ECMAScript Latest Draft (ECMA-262)
The definition of 'function*' in that specification.
Draft  

瀏覽器相容性

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
function*Chrome Full support 39Edge Full support 13Firefox Full support 26IE No support NoOpera Full support 26Safari Full support 10WebView Android Full support YesChrome Android Full support 39Firefox Android Full support 26Opera Android Full support YesSafari iOS Full support 10Samsung Internet Android Full support 4.0nodejs Full support 4.0.0
Full support 4.0.0
Full support 0.12
Disabled
Disabled From version 0.12: this feature is behind the --harmony runtime flag.
IteratorResult object instead of throwingChrome Full support 49Edge Full support 13Firefox Full support 29IE No support NoOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support 49Firefox Android Full support 29Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes
Not constructable with new (ES2016)Chrome Full support 50Edge Full support 13Firefox Full support 43IE No support NoOpera Full support 37Safari Full support 10WebView Android Full support 50Chrome Android Full support 50Firefox Android Full support 43Opera Android Full support 37Safari iOS Full support 10Samsung Internet Android Full support 5.0nodejs Full support Yes
Trailing comma in parametersChrome Full support 58Edge Full support 14Firefox Full support 52IE No support NoOpera Full support 45Safari ? WebView Android Full support 58Chrome Android Full support 58Firefox Android Full support 52Opera Android Full support 43Safari iOS ? Samsung Internet Android Full support 7.0nodejs Full support 8.0.0

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
User must explicitly enable this feature.
User must explicitly enable this feature.

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 regular function keyword (without an asterisk) among other differences. See Legacy generator function for further information.

IteratorResult object returned instead of throwing

Starting with Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26), the completed generator function no longer throws a TypeError "generator has already finished". Instead, it returns an IteratorResult object like { value: undefined, done: true } (bug 958951).

參見