ES2015 [6th edition] で let と const が導入された。var と書いてあるところにはこれらも書ける。
JavaScript の forは、次の2つの書き方がある。C/C++風の書き方と、in/of演算子を使った書き方。
コンテナの要素を単純に使いたいときは後者を使う。
for (式1; 式2; 式3) ... for (var宣言; 式2; 式3) ...
for (要素 in コンテナ) ... for (要素 of コンテナ) ...
for文1.変数の代入, 2.ループするかどうかの条件式, 3.変数の更新, の3つの引数を取る。2番目の条件式が真の間、ループされる。
下, 2番目の例のように, var宣言で関数スコープ (forブロックではない) の変数を宣言できる。現代は let を使うのが通常.
ES5 (2009年) にも for-in文があった。ES2015 (ES6) で, for-in文に加えて for-of文が導入された。書き方は非常に似ている。
in はキーワードだが, of はそうではない。文脈依存キーワードになっている。
for ( 左辺値in式 ) 文 for (varForBindingin式 ) 文 for ( ForDeclarationin式 ) 文
for ( 左辺値ofAssignmentExpression ) 文 for (varForBindingofAssignmentExpression ) 文 for ( ForDeclarationofAssignmentExpression ) 文
for-in文は、オブジェクトの全てのプロパティのうち [[Enumerable]] = true 属性を持つものを順に変数に代入し、それで文を実行する。
順序が先頭からとは限らない。余計なものが付く、という難点があり、実用的でない。次の例は配列だが、配列の要素ではなくインデックスになっているし、fn も渡されている。
in の後ろにオブジェクトを書いた場合は、key が順番に渡されてくる。
いずれにしても、新しいプログラムを書く際は, もはや for-in文は使うべきではない。
for-of文は, for文に渡されたオブジェクトが「反復可能 (iterable) オブジェクト」であるとき, そのオブジェクトの @@iterator プロパティを呼び出してイテレータ (後述) を得て, そのイテレータでループを回す。逆に, @@iterator プロパティを持つオブジェクトが iterable である。
配列 Array の場合は、ちゃんと配列の要素が順番に得られる。文字列 String だとそれぞれの code point. Map だと entries() の各要素, Set だと values() の各要素.
ただのハッシュオブジェクトだと、イテレータがないので, TypeError 例外になる。
新しいプログラムでは, for-of文のほうを使うようにすればいい。
配列を取りそうな場所は、配列決め打ちではなく, iterable オブジェクトであれば受け付けるようにすると汎用性が上がる。
イテレータを生成できるオブジェクトを iterable オブジェクトと呼ぶ。
イテレータは少なくとも next プロパティとして関数を持たなければならない。returnプロパティ (関数), throwプロパティ (関数) を持ってもよい。next() が返すオブジェクトは done, value のプロパティを持たなければならないき。
自分でイテレータを作るには、次のようにする;
上の例では iterator を obj とは別のオブジェクトにしたが、obj のプロパティとして next を定義すれば、iterable オブジェクトかつ iterator にすることもできる。