JavaScript/イテレータプロトコル
イテレータプロトコル
[編集]JavaScriptのイテレータプロトコルは、オブジェクトがfor...of
ループなどの反復処理で使用される際に、反復可能であることを定義するための規則です。イテレータプロトコルを実装することで、カスタムオブジェクトを反復可能にし、配列やマップ、セットと同じようにfor...of
ループを使用して繰り返し処理ができるようになります。
イテレータプロトコルは、主に2つのメソッドによって構成されます:
next()
メソッドSymbol.iterator
メソッド
next()
メソッド
[編集]イテレータオブジェクトは、next()
メソッドを持つ必要があります。このメソッドは、反復処理される各値を提供します。next()
は、done
プロパティとvalue
プロパティを含むオブジェクトを返します。
value
: 次に返される値done
: イテレーションが終了したかどうかを示すブール値(true
ならば反復終了、false
ならば続行)
例えば、次のジェネレータ関数は、next()
メソッドの挙動を示しています。
function* counter() { yield 1; yield 2; yield 3; } const iterator = counter(); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }
counter()
は、yield
を使って順番に値を返します。next()
メソッドが呼び出されるたびに、その時点のvalue
が返され、done
がfalse
の場合は反復を続けます。
Symbol.iterator
メソッド
[編集]イテレータプロトコルを満たすためには、対象のオブジェクトがSymbol.iterator
メソッドを持っている必要があります。このメソッドは、反復可能なオブジェクトに対してイテレータを返すメソッドです。
例えば、配列のイテレータは以下のように定義されています。
const arr = [1, 2, 3]; const iterator = arr[Symbol.iterator](); console.log(iterator.next()); // { value: 1, done: false } console.log(iterator.next()); // { value: 2, done: false } console.log(iterator.next()); // { value: 3, done: false } console.log(iterator.next()); // { value: undefined, done: true }
Symbol.iterator
メソッドは、反復可能なオブジェクト(配列、文字列、セット、マップなど)で標準で実装されています。このメソッドを自分で実装することで、カスタムオブジェクトもイテレータとして使えるようになります。
イテレータプロトコルのカスタム実装
[編集]独自のイテレータプロトコルを実装したい場合、next()
メソッドとSymbol.iterator
メソッドを提供する必要があります。例えば、以下のコードではカスタムオブジェクトに対してイテレータを実装しています。
const customIterable = { from: 1, to: 3, [Symbol.iterator]() { let current = this.from; const last = this.to; return { next() { if (current <= last) { return { value: current++, done: false }; } else { return { value: undefined, done: true }; } } }; } }; for (const num of customIterable) { console.log(num); // 1, 2, 3 }
この例では、customIterable
というオブジェクトがSymbol.iterator
を実装しており、next()
メソッドを使用して、1から3までの数値を順番に返します。
イテレータと反復可能なオブジェクト
[編集]イテレータプロトコルを実装したオブジェクトは、反復可能(iterable)なオブジェクトとなります。反復可能オブジェクトは、for...of
ループを使って反復処理することができます。反復可能オブジェクトは、[Symbol.iterator]()
メソッドを持っており、これによってイテレータを取得することができます。
const iterable = ['a', 'b', 'c']; for (const item of iterable) { console.log(item); // a, b, c }
この場合、配列iterable
は反復可能なオブジェクトであり、for...of
ループで順番に値を取り出すことができます。
イテレータプロトコルの利点
[編集]イテレータプロトコルを実装することにより、次のような利点があります:
- カスタムコレクションの反復処理: 独自のデータ構造を簡単に反復処理できるようにする。
- 遅延評価: 必要に応じて値を生成するジェネレータを使用することで、メモリ効率を向上させる。
- 無限シーケンスの扱いやすさ: 無限に続くシーケンス(例:自然数の列)を効率的に扱うことができる。