JavaScript/ジェネレータオブジェクト
ジェネレータオブジェクト
[編集]ジェネレータオブジェクトは、ジェネレータ関数によって返されるオブジェクトで、next()
メソッドを使ってその実行を制御することができます。ジェネレータオブジェクトは、反復可能な構造を持っており、next()
メソッドによって値を逐次的に返します。これにより、データの生成や非同期処理を効率的に管理することができます。
構造
[編集]ジェネレータオブジェクトは、next()
メソッドを提供するオブジェクトです。このメソッドは、ジェネレータ関数内の yield
ステートメントを一時停止させ、次回呼び出すとその位置から再開します。また、next()
はオブジェクトを返し、そのオブジェクトには以下の二つのプロパティがあります。
使用例
[編集]基本的な使用例
[編集]ジェネレータ関数を呼び出すと、ジェネレータオブジェクトが返されます。このオブジェクトの next()
メソッドを使って、値を逐次的に取得できます。
function* count() { yield 1; yield 2; yield 3; } const gen = count(); 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 }
この例では、count() 関数がジェネレータ関数であり、gen というジェネレータオブジェクトを通じて値を順番に取得します。
done
プロパティは、ジェネレータが終了したかどうかを示します。done
が true
の場合、それ以上の値は生成されません。
function* generator() { yield 'A'; yield 'B'; } const gen = 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 }
done: true
となると、ジェネレータ関数は終了しており、next()
を呼び出しても新たな値は生成されません。
value
プロパティには、yield
ステートメントで返された値が格納されます。next()
メソッドが呼び出されるたびに、この値は変化します。
function* letters() { yield 'X'; yield 'Y'; } const gen = letters(); console.log(gen.next().value); // 'X' console.log(gen.next().value); // 'Y'
ここでは、next().value
が順番に 'X'
と 'Y'
を返します。
引数を渡す
[編集]next()
メソッドには引数を渡すことができ、これによりジェネレータ内で 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'
gen.next('Received value')
で渡された引数は value
変数に設定され、console.log
によってその値が出力されます。
ジェネレータオブジェクトの特徴
[編集]- 一時停止と再開: ジェネレータオブジェクトは
next()
メソッドを使って実行を一時停止し、再開することができます。 - 遅延評価: ジェネレータオブジェクトは、必要な時にのみデータを生成します。これによりメモリの効率的な利用が可能になります。
- 反復可能: ジェネレータオブジェクトは、反復可能なインターフェース(
next()
メソッド)を提供し、データを逐次的に取得することができます。 - 状態の保持: ジェネレータオブジェクトは、各
yield
の位置を保持し、次回next()
が呼ばれたときにその位置から再開します。
使用シーン
[編集]ジェネレータオブジェクトは、次のようなシーンで有効です。
- 遅延データ処理: 一度に全てのデータを処理せず、必要に応じてデータを生成するため、メモリ効率が良くなります。
- 非同期処理の制御: 非同期処理を順次処理する場合、
yield
とnext()
を組み合わせて、非同期の処理を簡潔に制御できます。 - 状態管理: 複雑な状態の管理や、イベント駆動型のアプリケーションで利用されることがあります。
注意点
[編集]done
がtrue
の場合、そのジェネレータオブジェクトは終了しており、next()
を呼び出しても新しい値は生成されません。next()
メソッドで値を渡すことで、ジェネレータ関数内のyield
にデータを送り、状態を管理できます。- ジェネレータオブジェクトは反復可能であり、繰り返し処理を行うのに便利ですが、一度終了すると再利用できません。