これは Harmony(ECMAScript 2015 (ES6)) の一部です。
この技術の仕様は最終化されていますが、使用にあたってはブラウザーごとの実装状況の一覧表を確認してください。
function* 宣言 (末尾にアスタリスクが付いたfunctionキーワード)は、ジェネレーター関数を定義します。
ジェネレーター関数は、 GeneratorFunction コンストラクターとfunction* expressionを使用して定義することもできます。
構文
function* name([param[, param[, ... param]]]) {
statements
}
name- 関数名。
param- 関数に渡される引数名。引数は255個までもつことが可能。
statements- 関数本体に含まれる命令文。
解説
ジェネレーターは処理を抜け出すことも後から復帰することもできる関数です。ジェネレーターのコンテキスト (変数の値)は復帰しても保存されます。
ジェネレーター関数を呼び出しても関数は直ぐには実行されません。代わりに、関数のためのiterator オブジェクトが返されます。iterator の next() メソッドが呼ばれると、ジェネレーター関数の処理は、イテレーターから返された値を特定する最初のyield演算子か、ほかのジェネレーター関数に委任する yield*に達するまで実行されます。next() メソッドは生産された値を含む value プロパティとジェネレーターが最後の値を持つかを示す done プロパティを持つオブジェクトを返します。
例
単純な例
function* idMaker(){
var index = 0;
while (index < 3)
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); // undefined
// ...
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* f() {}
var obj = new f; // throws "TypeError: f is not a constructor"
仕様
| 仕様 | 状況 | コメント |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) function* の定義 |
標準 | 初期定義 |
| ECMAScript 2016 (ECMA-262) function* の定義 |
標準 | ジェネレーターは [[Construct]] トラップを持ってはならず、new と併用された場合は例外を送出するように変更されました。 |
| ECMAScript 2017 Draft (ECMA-262) function* の定義 |
ドラフト |
ブラウザー実装状況
| 機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
|---|---|---|---|---|---|
| 基本機能 | 39 | 26.0 (26.0) | 未サポート | 26 | 未サポート |
yield* |
(有) | 27.0 (27.0) | 未サポート | 26 | 未サポート |
IteratorResult object instead of throwing |
? | 29.0 (29.0) | 未サポート | ? | 未サポート |
| 機能 | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|
| 基本機能 | (有) | 26.0 (26.0) | 未サポート | 未サポート | 未サポート |
yield* |
(有) | 27.0 (27.0) | 未サポート | 未サポート | 未サポート |
IteratorResult object instead of throwing |
? | 29.0 (29.0) | 未サポート | 未サポート | 未サポート |
Firefox特有のメモ
Firefox26以前のジェネレーターとイテレーター
旧バージョンのFirefoxは旧仕様のジェネレーターを実装しています。旧バージョンでは、 ジェネレーターは違いとして通常の function キーワード(アスタリスクを用いない)を使用して定義されます。
スローの代わりにIteratorResultオブジェクトが返される
Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26)からは、完了したジェネレーター関数は TypeError"ジェネレーターはすでに完了しました"をもはやスローしません。かわりに、{ value: undefined, done: true }のような IteratorResult を返します (バグ 958951)。
関連項目
function* expressionGeneratorFunctionobject- The Iterator protocol
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
- Hemanth.HM: The New gen of *gen(){}
- Task.js