JavaScript 可迭代對象
可迭代對象是可以被迭代的對象(如數組)。
可迭代對象可以通過簡單高效的代碼訪問。
可迭代對象可以使用 for..of
循環進行迭代。
for..of 循環
for..of
語句用于遍歷可迭代對象的元素。
語法
for (variable of iterable) { // 要執行的代碼塊 }
迭代
迭代很容易理解。
它只是意味著遍歷一系列元素。
下面是一些簡單的例子:
- 遍歷字符串
- 遍歷數組
遍歷字符串
可以使用 for..of
循環遍歷字符串的元素:
實例
const name = "W3Schools"; for (const x of name) { // 要執行的代碼塊 }
遍歷數組
可以使用 for..of
循環遍歷數組的元素:
例子 1
const letters = ["a","b","c"]; for (const x of letters) { // 要執行的代碼塊 }
例子 2
const numbers = [2,4,6,8]; for (const x of numbers) { // 要執行的代碼塊 }
遍歷 Set
可以使用 for..of
循環遍歷 Set 的元素:
實例
const letters = new Set(["a","b","c"]); for (const x of letters) { // 要執行的代碼塊 }
注釋:我們將在后續章節中詳細介紹 Set 和 Map。
遍歷 Map
可以使用 for..of
循環遍歷 Map 的元素:
實例
const fruits = new Map([ ["apples", 500], ["bananas", 300], ["oranges", 200] ]); for (const x of fruits) { // 要執行的代碼塊 }
JavaScript 迭代器
迭代器協議定義了如何從對象中生成一系列值。
當對象實現了 next()
方法時,它就成為迭代器。
next()
方法必須返回一包含兩個屬性的對象:
- value(下一個值)
- done(true 或 false)
value |
迭代器返回的值。 如果 done 為 true,則可以省略。 |
done |
如果迭代器已完成,則為 true。 如果迭代器生成了新值,則為 false。 |
注意:
從技術上講,可迭代對象必須實現 Symbol.iterator 方法。
字符串、數組、TypedArray、Map 和 Set 都是可迭代對象,因為它們的原型對象具有 Symbol.iterator 方法。
自定義可迭代對象
下例展示了一個自定義的可迭代對象,它永遠不會結束,每次調用 next()
都會返回 10, 20, 30, 40, ...:
實例
// 自定義可迭代對象 function myNumbers() { let n = 0; return { next: function() { n += 10; return { value: n, done: false }; } }; } // 創建可迭代對象 const n = myNumbers(); n.next(); // 返回 10 n.next(); // 返回 20 n.next(); // 返回 30
問題是:
自定義的可迭代對象不支持 JavaScript 的 for..of
語句。
支持 for..of 的可迭代對象
JavaScript 可迭代對象是擁有 Symbol.iterator 的對象。
Symbol.iterator 是一個返回 next()
方法的函數。
可以使用以下代碼對可迭代對象進行迭代:
for (const x of iterable) { }
實例
// 創建一個對象 myNumbers = {}; // 使其可迭代 myNumbers[Symbol.iterator] = function() { let n = 0; done = false; return { next() { n += 10; if (n == 100) { done = true; } return { value: n, done: done }; } }; }; // 現在可以使用 for..of for (const num of myNumbers) { // 任意代碼 }
Symbol.iterator 方法會被 for..of
自動調用。
但我們也可以手動調用它:
實例
let iterator = myNumbers[Symbol.iterator](); while (true) { const result = iterator.next(); if (result.done) break; // 任意代碼 }