function* 宣言 (末尾にアスタリスクが付いたfunctionキーワード)は、 Generator オブジェクトを返すジェネレーター関数を定義します。

ジェネレーター関数は、 GeneratorFunction コンストラクターを使用して定義することもできます。

構文

function* name([param[, param[, ... param]]]) {
   statements
}
name
関数名。
param
関数に渡される引数名。引数は255個までもつことが可能。
statements
関数本体に含まれる命令文。

解説

ジェネレーターは処理を抜け出すことも後から復帰することもできる関数です。ジェネレーターのコンテキスト (変数の値)は復帰しても保存されます。

ジェネレーター関数を呼び出しても関数は直ぐには実行されません。代わりに、関数のためのiterator オブジェクトが返されます。iterator の next() メソッドが呼ばれると、ジェネレーター関数の処理は、イテレーターから返された値を特定する最初のyield演算子か、ほかのジェネレーター関数に委任する yield*に達するまで実行されます。next() メソッドはyieldされた値を含む value プロパティと、ジェネレーターが最後の値を持つかを真偽値で示す done プロパティを持つオブジェクトを返します。 引数つきでnext() を呼ぶとジェネレーター関数の実行が再開され、処理が停止していた yield 式を next() の引数で置き換えます。

return 文はジェネレーターで、実行された時、ジェネレーターを done にします。値が return(返却)されたら、value として返されます。値を返されたジェネレーターは、それ以降は値をyieldしません。

単純な例

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();

// 最初の next の呼び出しで、関数の最初から、
// 最初の yield 文の前まで実行される。
gen.next();             // 0
gen.next('pretzel');    // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise

ジェネレーターにおけるreturn文

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();
// {value: 10, done: false}
bar.next();

仕様

仕様 状況 コメント
ECMAScript 2015 (6th Edition, ECMA-262)
function* の定義
標準 初期定義
ECMAScript 2016 (ECMA-262)
function* の定義
標準 ジェネレーターは [[Construct]] トラップを持ってはならず、new と併用された場合は例外を送出するように変更されました。
ECMAScript Latest Draft (ECMA-262)
function* の定義
ドラフト  

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
基本対応Chrome 完全対応 39Edge 完全対応 13Firefox 完全対応 26IE 未対応 なしOpera 完全対応 26Safari 完全対応 10WebView Android 完全対応 ありChrome Android 完全対応 39Edge Mobile 完全対応 ありFirefox Android 完全対応 26Opera Android 完全対応 ありSafari iOS 完全対応 10Samsung Internet Android 完全対応 4.0nodejs 完全対応 4.0.0
完全対応 4.0.0
完全対応 0.12
無効
無効 From version 0.12: this feature is behind the --harmony runtime flag.
IteratorResult object instead of throwingChrome 完全対応 49Edge 完全対応 13Firefox 完全対応 29IE 未対応 なしOpera 完全対応 ありSafari 完全対応 ありWebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 完全対応 ありFirefox Android 完全対応 29Opera Android 完全対応 ありSafari iOS 完全対応 ありSamsung Internet Android 完全対応 ありnodejs 完全対応 あり
Not constructable with new (ES2016)Chrome 完全対応 ありEdge ? Firefox 完全対応 43IE 未対応 なしOpera 完全対応 ありSafari 完全対応 10WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile ? Firefox Android 完全対応 43Opera Android 完全対応 ありSafari iOS 完全対応 10Samsung Internet Android 完全対応 ありnodejs 完全対応 あり
Trailing comma in parametersChrome ? Edge ? Firefox 完全対応 52IE ? Opera 完全対応 ありSafari ? WebView Android ? Chrome Android ? Edge Mobile ? Firefox Android 完全対応 52Opera Android ? Safari iOS ? Samsung Internet Android ? nodejs 完全対応 8.0.0

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

Firefox特有のメモ

Firefox26以前のジェネレーターとイテレーター

旧バージョンのFirefoxは旧仕様のジェネレーターを実装しています。旧バージョンでは、 ジェネレーターは大きな違いとして通常の function キーワード(アスタリスクを用いない)を使用して定義されます。 更なる情報はレガシージェネレーター関数を見てください。

スローの代わりにIteratorResultオブジェクトが返される

Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26)からは、完了したジェネレーター関数は TypeError"ジェネレーターはすでに完了しました"をもはやスローしません。かわりに、{ value: undefined, done: true }のような IteratorResult を返します (バグ 958951)。

関連項目

ドキュメントのタグと貢献者

このページの貢献者: mandel59, Uemmra3, kdex, kei-itof, chikoski, lv7777, YuichiNukiyama
最終更新者: mandel59,