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

浏览器兼容性

另见