イテラブル
オブジェクトは、Symbol.iterator
プロパティの実装を持っている場合、反復可能とみなされます。 Array
、Map
、Set
、String
、Int32Array
、Uint32Array
など、いくつかの組み込み型は、すでに Symbol.iterator
プロパティが実装されています。オブジェクトの Symbol.iterator
関数は、反復処理を行う値のリストを返す役割を担います。
Iterable
インターフェース
Iterable
は、上記にリストされている反復可能な型を取り込みたい場合に使用できる型です。次に例を示します。
ts
function toArray<X>(xs: Iterable<X>): X[] {return [...xs]}
for..of
ステートメント
for..of
は、反復可能オブジェクトをループ処理し、オブジェクトの Symbol.iterator
プロパティを呼び出します。配列に対する単純な for..of
ループの例を次に示します。
ts
let someArray = [1, "string", false];for (let entry of someArray) {console.log(entry); // 1, "string", false}
for..of
ステートメントと for..in
ステートメントの比較
for..of
と for..in
ステートメントはどちらもリストを反復処理しますが、反復処理される値は異なります。 for..in
は、反復処理されるオブジェクトの*キー*のリストを返しますが、 for..of
は、反復処理されるオブジェクトの数値プロパティの*値*のリストを返します。
この違いを示す例を次に示します。
ts
let list = [4, 5, 6];for (let i in list) {console.log(i); // "0", "1", "2",}for (let i of list) {console.log(i); // 4, 5, 6}
もう1つの違いは、for..in
は任意のオブジェクトに対して動作し、このオブジェクトのプロパティを検査する方法として機能することです。一方、for..of
は、主に反復可能オブジェクトの値に関心があります。 Map
や Set
などの組み込みオブジェクトは、 Symbol.iterator
プロパティを実装しており、格納されている値へのアクセスを可能にします。
ts
let pets = new Set(["Cat", "Dog", "Hamster"]);pets["species"] = "mammals";for (let pet in pets) {console.log(pet); // "species"}for (let pet of pets) {console.log(pet); // "Cat", "Dog", "Hamster"}
コード生成
ES5とES3をターゲットにする
ES5またはES3準拠のエンジンをターゲットにする場合、イテレーターは `Array` 型の値に対してのみ許可されます。これらの非配列値が `Symbol.iterator` プロパティを実装している場合でも、非配列値で `for..of` ループを使用するとエラーになります。
コンパイラは、`for..of` ループに対して単純な `for` ループを生成します。たとえば、
ts
let numbers = [1, 2, 3];for (let num of numbers) {console.log(num);}
は、次のように生成されます。
js
var numbers = [1, 2, 3];for (var _i = 0; _i < numbers.length; _i++) {var num = numbers[_i];console.log(num);}
ECMAScript 2015 以上をターゲットとする
ECMAScript 2015 準拠のエンジンをターゲットとする場合、コンパイラはエンジンに組み込まれたイテレータ実装をターゲットとするために for..of
ループを生成します。