JavaScript/function*
function*
function* は、JavaScript でジェネレータ関数を定義するための構文です。ジェネレータ関数は、実行を途中で一時停止し、後で再開することができる特別な種類の関数です。function*
キーワードを使って定義された関数は、ジェネレータオブジェクトを返します。このオブジェクトには、反復処理を制御するための next()
メソッドや return()
メソッドが含まれています。
構文
function* functionName() { // ジェネレータ関数のコード }
使用例
基本的な使用例
function* greet() { yield 'Hello'; yield 'World'; } const greeting = greet(); console.log(greeting.next().value); // 'Hello' console.log(greeting.next().value); // 'World' console.log(greeting.next().value); // undefined
この例では、greet 関数は 2 回 yield
を使って値を返します。next()
メソッドでジェネレータ関数の実行を制御できます。
ループと組み合わせた使用例
function* numbers() { let i = 1; while (i <= 5) { yield i++; } } const iterator = numbers(); for (const num of iterator) { console.log(num); // 1, 2, 3, 4, 5 }
この例では、numbers ジェネレータ関数が 1 から 5 までの数字を順番に yield
し、for...of
ループを使って反復処理を行っています。
return
を使った終了
function* count() { yield 1; yield 2; return 'done'; } const counter = count(); console.log(counter.next().value); // 1 console.log(counter.next().value); // 2 console.log(counter.next().value); // 'done' console.log(counter.next().done); // true
ジェネレータ関数では、return
を使って明示的に終了することができます。終了後、done
プロパティが true
となり、それ以上の値は返されません。
yield
で受け取る値
function* process() { const value = yield 'Start'; console.log('Received:', value); yield 'End'; } const gen = process(); console.log(gen.next().value); // 'Start' gen.next('Received value'); // 'Received: Received value' console.log(gen.next().value); // 'End'
function*
を使って定義されたジェネレータ関数内で、yield
によって値を返し、呼び出し元から値を受け取ることができます。next()
メソッドに渡された引数は、yield
によって受け取られます。
実装例:自然数ジェネレータ
- naturals.js
function* naturals() { for (let n = 1; true; yield n++) {} } const naturalsGen = naturals(); const result = naturalsGen .drop(3) .take(5) .map(n => n * 2 + 1) .toArray(); console.log(result); // [9, 11, 13, 15, 17]
ES2024では、ジェネレーターに便利なイテレーションメソッド(drop, take, map, toArrayなど)が直接組み込まれ、コードが簡潔に書けるようになっています。