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にデータを送り、状態を管理できます。- ジェネレータオブジェクトは反復可能であり、繰り返し処理を行うのに便利ですが、一度終了すると再利用できません。