JavaScriptの反復処理はプロトコルとして実装されています。反復処理プロトコルは反復可能プロトコル(Iterable protocol)と反復子プロトコル(Iterator protocol)からなり、これらはオブジェクトが次表の条件を満たすことを求めます。
プロトコルはあくまでも条件であり、C++やC#のようにインターフェイスやクラスの継承は求めません。
プロトコル | 条件 |
---|---|
反復可能プロトコル | 反復子プロトコルを満たすオブジェクトを返す引数なしのメソッド[Symbol.iterator]() を持つ。 |
反復子プロトコル | 次のプロパティを持つオブジェクトを返す引数なしのメソッドnext() を持つ。done :反復処理の終了を表すBoolean 型の値(true で反復終了)、value :任意の型の反復結果(done がtrue なら省略可能)。 |
例えば、次のコードの変数o1
は反復処理プロトコルを満たし、その[Symbol.iterator]
メソッドの戻り値は反復子プロトコルを満たします。
const o1 = { [Symbol.iterator]() { return { i: 1, next() {return {done: this.i == 4, value: this.i++};} }; } }; console.log([...o1]); // [1, 2, 3]
反復処理は主に以下で使用されます。
- for (const value of iterable)
- [...iterable]
なお、反復子はジェネレータ関数function*
を用いて簡単に定義できます。
const o1 = { [Symbol.iterator]: function* () { yield 1; yield 2; yield 3; } }; console.log([...o1]); // [1, 2, 3]
ジェネレータ関数の簡略表記も使えます。
const o1 = { *[Symbol.iterator]() { yield 1; yield 2; yield 3; } }; console.log([...o1]); // [1, 2, 3]
参考