迭代器()构造函数

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

Iterator() 构造函数旨在用作创建迭代器的其他类的 superclass。当它自己构造时会抛出错误。

¥The Iterator() constructor is intended to be used as the superclass of other classes that create iterators. It throws an error when constructed by itself.

语法

¥Syntax

js
new Iterator()

注意:Iterator() 只能与 new 一起构建。尝试在没有 new 的情况下调用它会抛出 TypeError。此外,Iterator() 实际上不能自行构造 - 它通常是通过子类的构造函数内的 super() 调用隐式构造的。

¥Note: Iterator() can only be constructed with new. Attempting to call it without new throws a TypeError. In addition, Iterator() cannot actually be constructed itself — it's usually implicitly constructed through super() calls inside the constructor of a subclass.

参数

¥Parameters

没有任何。

¥None.

返回值

¥Return value

一个新的 Iterator 对象。

¥A new Iterator object.

例外情况

¥Exceptions

TypeError

new.targetIterator 函数本身时,即当 Iterator 构造函数本身被构造时。

描述

¥Description

Iterator 代表一个抽象类 - 为其子类提供通用实用程序的类,但并不打算自行实例化。它是所有其他迭代器类的超类,用于创建实现特定迭代算法的子类 - 即,Iterator 的所有子类必须按照 迭代器协议 的要求实现 next() 方法。因为 Iterator 实际上并没有提供 next() 方法,所以直接构造 Iterator 是没有意义的。

¥Iterator represents an abstract class — a class that provides common utilities for its subclasses, but is not intended to be instantiated itself. It is the superclass of all other iterator classes, and is used to create subclasses that implement specific iteration algorithms — namely, all subclasses of Iterator must implement a next() method as required by the iterator protocol. Because Iterator doesn't actually provide the next() method, it doesn't make sense to construct an Iterator directly.

你还可以使用 Iterator.from() 从现有的可迭代对象或迭代器对象创建 Iterator 实例。

¥You can also use Iterator.from() to create an Iterator instance from an existing iterable or iterator object.

示例

¥Examples

子类化迭代器

¥Subclassing Iterator

以下示例定义了允许迭代的自定义数据结构 Range。使对象可迭代的最简单方法是以生成器函数的形式提供 [@@iterator]() 方法:

¥The following example defines a custom data structure, Range, which allows iteration. The simplest way to make an object iterable is to provide an [@@iterator]() method in the form of a generator function:

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);
}

这是可行的,但它不如内置迭代器的工作方式那么好。有两个问题:

¥This works, but it isn't as nice as how built-in iterators work. There are two problems:

  • 返回的迭代器继承自 Generator,这意味着对 Generator.prototype 的修改将影响返回的迭代器,这是抽象的泄漏。
  • 返回的迭代器不继承自自定义原型,这使得如果我们打算向迭代器添加额外的方法会变得更加困难。

我们可以通过子类化 Iterator 来模仿内置迭代器的实现,例如 地图迭代器。这使我们能够定义额外的属性,例如 @@toStringTag,同时使迭代器辅助方法在返回的迭代器上可用。

¥We can mimic the implementation of built-in iterators, such as map iterators, by subclassing Iterator. This enables us to define extra properties, such as @@toStringTag, while making the iterator helper methods available on the returned iterator.

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 实例。

¥The subclassing pattern is useful if you want to create many custom iterators. If you have an existing iterable or iterator object which doesn't inherit from Iterator, and you just want to call iterator helper methods on it, you can use Iterator.from() to create a one-time Iterator instance.

规范

Specification
Iterator Helpers
# sec-iterator-constructor

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看