迭代器和生成器

可迭代物件

如果物件已實作 Symbol.iterator 屬性,則此物件視為可迭代。某些內建型別,例如 ArrayMapSetStringInt32ArrayUint32Array 等,已實作其 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..offor..in 陳述式

for..offor..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
}

另一項區別是 for..in 可用於任何物件;它用於檢查此物件的屬性。另一方面,for..of 主要用於可迭代物件的值。內建物件(例如 MapSet)會實作 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 類型的值上使用迭代器。在非陣列值上使用 for..of 迴圈會產生錯誤,即使這些非陣列值實作 Symbol.iterator 屬性也是如此。

編譯器會為 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 迴圈,以鎖定引擎中的內建迭代器實作。

TypeScript 文件是一個開放原始碼專案。協助我們改善這些頁面 傳送 Pull Request

此頁面的貢獻者
MHMohamed Hegazy (57)
OTOrta Therox (15)
GBGabriel Burdeti (3)
NSNick Schonning (1)
JYJason Yu (1)
11+

最後更新:2024 年 3 月 21 日