イテレーターとジェネレーター

オブジェクトがSymbol.iteratorプロパティを実装する場合、そのオブジェクトは反復可能(iterable)であるとみなされます。

Array、Map、Set、String、Int32Array、Uint32Array等の幾つかの組み込みの型には、 予めSymbol.iteratorプロパティが実装されており、 オブジェクトのSymbol.iterator関数は、反復処理上で値のリストを返すことを保証します。

for..of 文

for..ofは反復可能なオブジェクトの繰り返し処理を行う際に、Symbol.iteratorプロパティを実行します。 下記は配列でのシンプルなfor..ofの繰り返し処理になります。

let someArray = [1, "string", false];

for (let entry of someArray) {
    console.log(entry); // 1, "string", false
}

for..of vs for..in 文

for..offor..in文は、どちらもリストを繰り返し処理するものですが、その繰り返す値が異なり、 for..inはオブジェクトのキーのリストを返しますが、 for..ofはオブジェクトの数値プロパティの値のリストを返します。

両者の違いのデモを下記に示します。

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"
}

その他の違いにfor..inは任意のオブジェクト上で、 そのオブジェクトのプロパティを調べる方法を提供します。 一方、for..ofは反復可能なオブジェクトの値に主眼を置いています。 MapやSetなどの組み込みオブジェクトは、格納された値にアクセスするためのSymbol.iteratorプロパティを実装しています。

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";  //※ 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型でのみ使用することができます。 for..ofのループを非配列の値で使用すると、 例えそれらの値がSymbol.iteratorプロパティを実装していたとしてもエラーになります。

コンパイラはfor..ofループを、単純なforループにして生成します。下記はその例になります。

let numbers = [1, 2, 3];
for (let num of numbers) {
    console.log(num);
}

上記は次のように生成されます。

var numbers = [1, 2, 3];
for (var _i = 0; _i < numbers.length; _i++) {
    var num = numbers[_i];
    console.log(num);
}
ECMAScript 2015以上を対象とする場合

ECMAScipt 2015に準拠したエンジンを対象とする場合、 コンパイラはそのエンジンに実装されている組み込みのイテレーターを対象としてfor..ofを生成します。

 Back to top

© https://github.com/Microsoft/TypeScript-Handbook

このページは、ページトップのリンク先のTypeScript-Handbook内のページを翻訳した内容を基に構成されています。 下記の項目を確認し、必要に応じて公式のドキュメントをご確認ください。 もし、誤訳などの間違いを見つけましたら、 @tomofまで教えていただければ幸いです。

  • ドキュメントの情報が古い可能性があります。
  • "訳注:"などの断わりを入れた上で、日本人向けの情報やより分かり易くするための追記を行っている事があります。