表示されているページは、編集用 バージョンの MDN Web Docsです

MDN Web Docs のユーザーとして表示: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/function*

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

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

構文

function* name([param[, param[, ... param]]]) {
   statements
}
name
関数名。
param Optional
関数の形式上の引数の名前。
statements
関数の本体を構成する文。

解説

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

JavaScript のジェネレータは、特にプロミスと組み合わせることで、非同期プログラミングのための非常に強力なツールとなり、 Callback HellInversion of Control などのようなコールバックの問題を、完全に解決できるわけではないものの、軽減することができます。しかし、これらの問題は非同期関数を使用すると、さらにシンプルに解決することができます。

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

ジェネレーターで return 文が実行されると、ジェネレーターが終了します (つまり、それによって返されたオブジェクトの done プロパティが true に設定されます)。値が返された場合、それはジェネレーターによって返されたオブジェクトの value プロパティとして設定されます。 return 文とよく似ていますが、ジェネレーターの内部でエラーが発生した場合は、ジェネレーターの本体の中でキャッチしない限り、ジェネレーターは終了します。
ジェネレーターが終了すると、それ以降の next() の呼び出しでは、そのジェネレーターのコードは実行されず、 {value: undefined, done: true} の形のオブジェクトが返されるだけです。

単純な例

function* idMaker() {
  var index = 0;
  while (true)
    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 }

オブジェクトプロパティとしてのジェネレーター

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() {}
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}

ジェネレーターの例

function* powers(n){
     //endless loop to generate
     for(let current =n;; current *= n){
         yield current;
     }
}

for(let power of powers(2)){
     //controlling generator
     if(power > 32) break;
     console.log(power)
           //2
          //4
         //8
        //16
       //32
}

仕様書

仕様書
ECMAScript (ECMA-262)
function* の定義

ブラウザーの互換性

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
function*Chrome 完全対応 39Edge 完全対応 13Firefox 完全対応 26IE 未対応 なしOpera 完全対応 26Safari 完全対応 10WebView Android 完全対応 39Chrome Android 完全対応 39Firefox Android 完全対応 26Opera Android 完全対応 26Safari 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 完全対応 36Safari 完全対応 10WebView Android 完全対応 49Chrome Android 完全対応 49Firefox Android 完全対応 29Opera Android 完全対応 36Safari iOS 完全対応 10Samsung Internet Android 完全対応 5.0nodejs 完全対応 6.0.0
Not constructable with new (ES2016)Chrome 完全対応 50Edge 完全対応 13Firefox 完全対応 43IE 未対応 なしOpera 完全対応 37Safari 完全対応 10WebView Android 完全対応 50Chrome Android 完全対応 50Firefox Android 完全対応 43Opera Android 完全対応 37Safari iOS 完全対応 10Samsung Internet Android 完全対応 5.0nodejs 完全対応 6.0.0
Trailing comma in parametersChrome 完全対応 58Edge 完全対応 14Firefox 完全対応 52IE 未対応 なしOpera 完全対応 45Safari 完全対応 10WebView Android 完全対応 58Chrome Android 完全対応 58Firefox Android 完全対応 52Opera Android 完全対応 43Safari iOS 完全対応 10Samsung Internet Android 完全対応 7.0nodejs 完全対応 8.0.0

凡例

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

関連情報

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

最終更新者: mpcjazz,