Iterator() 建構函式

基準線 2025
新推出

自 ⁨2025 年 3 月⁩ 起,此功能可在最新的裝置和瀏覽器版本上使用。此功能可能在舊裝置或瀏覽器上無法正常工作。

Iterator() 建構函式旨在用作建立迭代器的其他類的超類。它在自身被構造時會丟擲錯誤。

語法

js
new Iterator()

注意: Iterator() 只能使用 new 來構造。嘗試在沒有 new 的情況下呼叫它會丟擲 TypeError。此外,Iterator() 本身實際上無法被構造——它通常是透過子類建構函式中的 super() 呼叫而隱式構造的。

引數

無。

返回值

一個新的 Iterator 物件。

異常

TypeError

new.targetIterator 函式本身時,即當 Iterator 建構函式本身被構造時。

描述

Iterator 代表一個抽象類——一個為子類提供通用實用程式的類,但本身不打算被例項化。它是所有其他迭代器類的超類,用於建立實現特定迭代演算法的子類——即,所有 Iterator 的子類都必須根據 迭代器協議 實現 next() 方法。由於 Iterator 實際上不提供 next() 方法,因此直接構造 Iterator 沒有意義。

您還可以使用 Iterator.from() 從現有的可迭代物件或迭代器物件建立 Iterator 例項。

示例

繼承 Iterator

以下示例定義了一個自定義資料結構 Range,它允許迭代。為了使物件可迭代,我們可以提供一個生成器函式形式的 [Symbol.iterator]() 方法。

js
class Range {
  #start;
  #end;
  #step;

  constructor(start, end, step = 1) {
    this.#start = start;
    this.#end = end;
    this.#step = step;
  }

  *[Symbol.iterator]() {
    for (let value = this.#start; value <= this.#end; value += this.#step) {
      yield value;
    }
  }
}

const range = new Range(1, 5);
for (const num of range) {
  console.log(num);
}

這可行,但不如內建迭代器那樣好。有兩個問題:

  • 返回的迭代器繼承自 Generator,這意味著對 Generator.prototype 的修改將影響返回的迭代器,這是一個抽象洩露。
  • 返回的迭代器不繼承自定義原型,這使得如果我們想向迭代器新增額外方法會更加困難。

我們可以透過繼承 Iterator 來模仿內建迭代器(例如 map 迭代器)的實現。這使我們能夠定義額外的屬性,例如 [Symbol.toStringTag],同時使迭代器輔助方法在返回的迭代器上可用。

js
class Range {
  #start;
  #end;
  #step;

  constructor(start, end, step = 1) {
    this.#start = start;
    this.#end = end;
    this.#step = step;
  }

  static #RangeIterator = class extends Iterator {
    #cur;
    #s;
    #e;
    constructor(range) {
      super();
      this.#cur = range.#start;
      this.#s = range.#step;
      this.#e = range.#end;
    }
    static {
      Object.defineProperty(this.prototype, Symbol.toStringTag, {
        value: "Range Iterator",
        configurable: true,
        enumerable: false,
        writable: false,
      });

      // Avoid #RangeIterator from being accessible outside
      delete this.prototype.constructor;
    }
    next() {
      if (this.#cur > this.#e) {
        return { value: undefined, done: true };
      }
      const res = { value: this.#cur, done: false };
      this.#cur += this.#s;
      return res;
    }
  };

  [Symbol.iterator]() {
    return new Range.#RangeIterator(this);
  }
}

const range = new Range(1, 5);
for (const num of range) {
  console.log(num);
}

如果您想建立許多自定義迭代器,繼承模式很有用。如果您有一個現有的可迭代物件或迭代器物件,它不繼承自 Iterator,而您只想在其上呼叫迭代器輔助方法,您可以使用 Iterator.from() 來建立一個一次性的 Iterator 例項。

規範

規範
ECMAScript® 2026 語言規範
# sec-iterator-constructor

瀏覽器相容性

另見