Javascript の for...of
for...in文
に対して ES2015で新しく追加された構文にfor...of文
がある。
for...of
は、配列などの列挙可能なオブジェクト(NodeList
, arguments
など)、イテレーター/ジェネレーターなどを処理できる。
■ for...ofの構文
for (仮変数 of 列挙可能なオブジェクト) { 命令 }
見た目はfor...in
とそっくりであるが、prototype要素
を処理しない、キーでなく値を列挙するなどの違いがある。
// forof.js let data = ['A', 'B', 'C']; Array.prototype.foo = {D:'D'}; for (let val of data) { console.log(val); }
$ node forof.js A B C
配列の出力に使ったfor...in
のコードをfor...of
用に変えただけだが、きちんと対象の配列直属の要素だけが列挙されている。
for...in
はDOMのコレクションを扱える
for...in
がイテラブル・オブジェクトを扱えるので、コード上に書かれた配列以外にも例えばDOMのコレクションを列挙できる。
例えば次のようなHTML
<ul> <li>item1</li> <li>item2</li> <li>item3</li> </ul>
let lis = document.getElementsByTagName( 'li' ); for (val of lis) { console.log(val); }
ブラウザの開発ツールのコンソールに次のように出力される。
<li>item1</li> <li>item2</li> <li>item3</li>
for...in
はイテラブル・オブジェクトを扱う
これはHTMLに書かれた<ul>...<li>...
タグのDOMが,
prototype属性
にiterator
を持っているからだ。
console.log(lis);
// ブラウザのコンソールに表示された`__proto__`プロパティに`Symbol.iterator`が含まれている
__proto__
..........
Symbol(Symbol.iterator) :
......
iterator
を持つオブジェクトを扱うfor...of
文は、Map、Set、String、TypedArray…などのイテラブル・オブジェクトを扱える。
一番シンプルな例は文字列(Stringオブジェクト)。
let str = "Hello"; for (let ch of str) { console.log(ch); }
$ node forof.js H e l l o
console.log(str.__proto__); // Stringオブジェクトもイテレーターを持っている。 String ................ Symbol(Symbol.iterator): ƒ [Symbol.iterator]() ............
for...in
はSymbol.iterator
を持たない通常のオブジェクトを扱えない
逆に通常のオブジェクトはそのままではイテレータを持っていないので、for..
in
で扱えない。
let data = {a: 100, b: 150, c: 200}; for (let val of data) { console.log(val); }
$ node forof.js ........... for (let val of data) { ^ TypeError: data is not iterable ..........
逆に言えば通常のオブジェクトであっても、自分でイテレータを実装できればfor...of
で列挙できるが、ここは難しいのでまた後日まとめることにする。