可迭代物件
如果物件已實作 Symbol.iterator 屬性,則此物件視為可迭代。某些內建型別,例如 Array、Map、Set、String、Int32Array、Uint32Array 等,已實作其 Symbol.iterator 屬性。物件上的 Symbol.iterator 函式負責傳回要迭代的值清單。
Iterable 介面
如果我們要使用上面列出的可迭代型別,可以使用 Iterable 型別。以下為範例
tsfunction toArray<X>(xs: Iterable<X>): X[] {return [...xs]}
for..of 陳述式
for..of 會迴圈處理可迭代物件,並呼叫物件上的 Symbol.iterator 屬性。以下是在陣列上使用簡單的 for..of 迴圈
tslet 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 會傳回正在迭代物件的數字屬性的值清單。
以下範例說明此區別
tslet 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 屬性,允許存取儲存的值。
tslet 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 類型的值上使用迭代器。在非陣列值上使用 for..of 迴圈會產生錯誤,即使這些非陣列值實作 Symbol.iterator 屬性也是如此。
編譯器會為 for..of 迴圈產生一個簡單的 for 迴圈,例如
tslet numbers = [1, 2, 3];for (let num of numbers) {console.log(num);}
會產生為
jsvar 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 迴圈,以鎖定引擎中的內建迭代器實作。