Iteratorについて
前回は「Symbol」について説明しました
今回は「Iterator」についてです
「Iterator」、「Iterable」の順番で説明します
Iterator
Iteratorとは・・
- 次の要素(IteratorResult)へ1つずつアクセスする方法を備えたオブジェクト
- nextメソッドを持っていて、nextメソッドがIteratorResultを返す
- IteratorResultはvalueプロパティとdoneプロパティを持っているオブジェクト
文章だとよくわかりませんね汗
上記の定義をコードにするとこんな感じになります
var index = 0; var array = [1, 2, 3]; var iterator = {}; // Iteratorはオブジェクト iterator.next = function () { // nextメソッドを持っている // valueプロパティとdoneプロパティを持っているIteratorResult var iteratorResult = { value: array[index++], done: index > array.length }; return iteratorResult; // nextメソッドはIteratorResultを返す };
コードにするとたったこれだけです
Iteratorは次の要素へのアクセスする方法を提供するだけで 実際の繰り返し処理は外部に任せます
IteratorResultの各プロパティですが
Iterable
Iterableとは・・
これも文章だとさっぱりですねw
コードで表現してみます
var iterable = {}; // Iterableはオブジェクト iterable[Symbol.iterator] = function() { // [Symbol.iterator]メソッドを持ってる return iterator; // Iteratorを返す };
前回説明したSymbol.iteratorを使ってますね
それ以外は簡単なコードです
では実際にIteratorを使ってみます
実践
var obj = {}; obj[Symbol.iterator] = function() { var index = 0; var array = [1, 2, 3]; var iterator = {}; iterator.next = function () { var iteratorResult = { value: array[index++], done: index > array.length }; return iteratorResult; }; return iterator; }; var iterator = obj[Symbol.iterator](); console.log(iterator.next()); // Object {value: 1, done: false} console.log(iterator.next()); // Object {value: 2, done: false} console.log(iterator.next()); // Object {value: 3, done: false} console.log(iterator.next()); // Object {value: undefined, done: true} /* whileを使った場合 var iterator = obj[Symbol.iterator](); var iteratorResult; while (true) { iteratorResult = iterator.next(); if (iteratorResult.done) { break; } console.log(iteratorResult.value); } */
上記を実際に実行してみると、順番に値を取り出すことができます
ただ、この書き方だと値の取り出し方が冗長でめんどくさいですね
そこでES2015で用意されたのがfor (var v of iterable)
構文です
上記の繰り返し処理はこんな感じで書けます
for (let v of obj) { console.log(v); }
スッキリしましたね
Iterableの定義さえ守っていれば、自作のオブジェクトもfor (var v of iterable)
構文に渡せます
内部でwhileを使った場合の処理が行われています
ビルトインのString、Array、TypedArray、Map、Setなども反復処理が可能なオブジェクトです
for (let v of [0, 1, 2]) console.log(v); /* 0 1 2 */ for (let v of 'abc') console.log(v); /* a b c */
まとめ
- Iteratorはnextメソッドを持ち、nextメソッドを呼ぶとIteratorResultを返す
- Iterableは[Symbol.iterator]メソッドを持ち、[Symbol.iterator]メソッドを呼ぶとIteratorを返す
for (var v of iterable)
構文を使うと、簡単に値を取り出せる
そして、ジェネレータ関数で作成されるジェネレータがIterableなオブジェクトです
詳しくは次の回で