function* 宣言

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.

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

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

試してみましょう

function* generator(i) { yield i; yield i + 10; } const gen = generator(10); console.log(gen.next().value); // Expected output: 10 console.log(gen.next().value); // Expected output: 20 

構文

js
function* name(param0) { statements } function* name(param0, param1) { statements } function* name(param0, param1, /* … ,*/ paramN) { statements } 

メモ: ジェネレーター関数には、対応するアロー関数はありません。

引数

name

関数名。

param省略可

関数の形式上の引数の名前。

statements

関数の本体を構成する文。

解説

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

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

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

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

function* 宣言はスコープの先頭に巻き上げられ、そのスコープのどこからでも呼び出すことができます。

単純な例

js
function* idMaker() { let index = 0; while (true) { yield index++; } } const 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* を使用した例

js
function* anotherGenerator(i) { yield i + 1; yield i + 2; yield i + 3; } function* generator(i) { yield i; yield* anotherGenerator(i); yield i + 10; } const 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 

ジェネレーターに引数を渡す

js
function* logGenerator() { console.log(0); console.log(1, yield); console.log(2, yield); console.log(3, yield); } const gen = logGenerator(); // 最初の next の呼び出しで、関数の最初から、 // 最初の yield 文の前まで実行される。 gen.next(); // 0 gen.next("pretzel"); // 1 pretzel gen.next("california"); // 2 california gen.next("mayonnaise"); // 3 mayonnaise 

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

js
function* yieldAndReturn() { yield "Y"; return "R"; yield "unreachable"; } const 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 } 

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

js
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 } 

オブジェクトメソッドとしてのジェネレーター

js
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 } 

計算プロパティとしてのジェネレーター

js
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' ] 

ジェネレーターはコンストラクターではない

js
function* f() {} const obj = new f(); // throws "TypeError: f is not a constructor 

式で定義されたジェネレーター

js
const foo = function* () { yield 10; yield 20; }; const bar = foo(); console.log(bar.next()); // {value: 10, done: false} 

ジェネレーターの例

js
function* powers(n) { //endless loop to generate for (let current = n; ; current *= n) { yield current; } } for (const power of powers(2)) { // controlling generator if (power > 32) { break; } console.log(power); // 2 // 4 // 8 // 16 // 32 } 

仕様書

Specification
ECMAScript® 2026 Language Specification
# sec-generator-function-definitions

ブラウザーの互換性

関連情報