JavaScript/function*

カテゴリ:Book:JavaScript#function*%20

function*

function* は、JavaScript でジェネレータ関数を定義するための構文です。ジェネレータ関数は、実行を途中で一時停止し、後で再開することができる特別な種類の関数です。function* キーワードを使って定義された関数は、ジェネレータオブジェクトを返します。このオブジェクトには、反復処理を制御するための next() メソッドや return() メソッドが含まれています。

構文

function* functionName() {
  // ジェネレータ関数のコード
}

function* を使うことで、関数がジェネレータ関数として定義され、yield を使って値を返すことができます。

使用例

基本的な使用例

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など)が直接組み込まれ、コードが簡潔に書けるようになっています。

使用の注意点

  • ジェネレータ関数は、通常の関数と異なり、yield を使うことで実行を一時停止し、呼び出し元が next() を呼ぶたびに再開します。そのため、関数が複数回の実行を繰り返すような状況で使用されます。
  • function* を使って定義された関数は、必ずジェネレータオブジェクトを返します。このオブジェクトは、next()return() メソッドを持ち、反復処理を制御します。

関連項目

参考

カテゴリ:JavaScript
カテゴリ:Book:JavaScript カテゴリ:JavaScript カテゴリ:Pages using the JsonConfig extension