Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Iterator()-Konstruktor

Baseline 2025
Neu verfügbar

Seit März 2025 funktioniert diese Funktion auf aktuellen Geräten und in aktuellen Browserversionen. Auf älteren Geräten oder in älteren Browsern funktioniert sie möglicherweise nicht.

Der Iterator()-Konstruktor ist als Oberklasse für andere Klassen gedacht, die Iteratoren erzeugen. Wird er selbst direkt instanziiert, löst er einen Fehler aus.

Syntax

js
new Iterator()

Hinweis: Iterator() kann nur mit new aufgerufen werden. Ein Aufruf ohne new löst einen TypeError aus. Außerdem kann Iterator() nicht direkt instanziiert werden – die Instanziierung erfolgt normalerweise implizit durch einen Aufruf von super() im Konstruktor einer Unterklasse.

Parameter

Keine.

Rückgabewert

Ein neues Iterator-Objekt.

Ausnahmen

TypeError

Wenn new.target die Iterator-Funktion selbst ist, der Iterator-Konstruktor also direkt instanziiert wird.

Beschreibung

Iterator ist eine abstrakte Klasse: Sie stellt ihren Unterklassen gemeinsame Funktionen bereit, ist aber nicht dafür vorgesehen, selbst instanziiert zu werden. Sie ist die Oberklasse aller anderen Iterator-Klassen und dient als Grundlage für Unterklassen, die bestimmte Iterationsalgorithmen implementieren. Dazu muss jede Unterklasse von Iterator eine next()-Methode implementieren, wie es das Iterator-Protokoll verlangt. Da Iterator selbst keine next()-Methode bereitstellt, ist es nicht sinnvoll, Iterator direkt zu instanziieren.

Sie können auch Iterator.from() verwenden, um aus einem vorhandenen iterierbaren Objekt oder Iterator-Objekt eine Iterator-Instanz zu erstellen.

Beispiele

Eine Unterklasse von Iterator erstellen

Das folgende Beispiel definiert eine benutzerdefinierte Datenstruktur namens Range, über die iteriert werden kann. Um ein Objekt iterierbar zu machen, können wir eine [Symbol.iterator]()-Methode in Form einer Generatorfunktion bereitstellen:

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

Das funktioniert, ist aber nicht so elegant wie die Funktionsweise integrierter Iteratoren. Es gibt zwei Probleme:

  • Der zurückgegebene Iterator erbt von Generator. Dadurch wirken sich Änderungen an Generator.prototype auf ihn aus, was die Abstraktion durchbricht.
  • Der zurückgegebene Iterator erbt nicht von einem benutzerdefinierten Prototyp. Das erschwert es, dem Iterator zusätzliche Methoden hinzuzufügen.

Wir können die Implementierung integrierter Iteratoren, etwa der Map-Iteratoren, nachbilden, indem wir eine Unterklasse von Iterator erstellen. So können wir zusätzliche Eigenschaften wie [Symbol.toStringTag] definieren, während die Iterator-Hilfsmethoden für den zurückgegebenen Iterator verfügbar sind.

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

Dieses Muster eignet sich, wenn Sie viele benutzerdefinierte Iteratoren erstellen möchten. Wenn Sie bereits ein iterierbares Objekt oder Iterator-Objekt haben, das nicht von Iterator erbt, und lediglich Iterator-Hilfsmethoden darauf aufrufen möchten, können Sie mit Iterator.from() eine einmalige Iterator-Instanz erstellen.

Spezifikationen

Spezifikation
ECMAScript® 2027 Language Specification
# sec-iterator-constructor

Browser-Kompatibilität

Siehe auch