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;
  // 任意代碼
}

親自試一試