`Iterator()` Konstruktor
Baseline
2025
Newly available
Since March 2025, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.
Der Iterator() Konstruktor ist vorgesehen, als Oberklasse anderer Klassen verwendet zu werden, die Iteratoren erstellen. Er erzeugt einen Fehler, wenn er alleine instanziiert wird.
Syntax
new Iterator()
Parameter
Keine.
Rückgabewert
Ein neues Iterator Objekt.
Ausnahmen
TypeError-
Wenn
new.targetdieIteratorFunktion selbst ist, d.h. wenn derIteratorKonstruktor selbst konstruiert wird.
Beschreibung
Iterator stellt eine abstrakte Klasse dar — eine Klasse, die allgemeine Dienstprogramme für ihre Unterklassen bereitstellt, aber nicht selbst instanziiert werden soll. Sie ist die Oberklasse aller anderen Iterator-Klassen und wird verwendet, um Unterklassen zu erstellen, die spezifische Iterationsalgorithmen implementieren — nämlich müssen alle Unterklassen von Iterator eine next() Methode implementieren, wie es das Iterator-Protokoll erfordert. Da Iterator die next() Methode tatsächlich nicht bereitstellt, macht es keinen Sinn, einen Iterator direkt zu konstruieren.
Sie können auch Iterator.from() verwenden, um eine Iterator Instanz aus einem vorhandenen iterierbaren oder Iterator-Objekt zu erstellen.
Beispiele
>Unterklassen von Iterator
Das folgende Beispiel definiert eine benutzerdefinierte Datenstruktur, Range, die Iteration ermöglicht. Um ein Objekt iterierbar zu machen, können wir eine [Symbol.iterator]() Methode in Form einer Generatorfunktion bereitstellen:
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);
}
Dies funktioniert, ist aber nicht so elegant wie die Arbeitsweise eingebauter Iteratoren. Es gibt zwei Probleme:
- Der zurückgegebene Iterator erbt von
Generator, was bedeutet, dass Änderungen anGenerator.prototypeden zurückgegebenen Iterator beeinflussen, was ein Abstraktionsleck darstellt. - Der zurückgegebene Iterator erbt nicht von einem benutzerdefinierten Prototyp, wodurch es schwieriger wird, wenn wir zusätzliche Methoden zum Iterator hinzufügen möchten.
Wir können die Implementierung eingebauter Iteratoren, wie z.B. Map-Iteratoren, nachahmen, indem wir Iterator als Unterklasse verwenden. Dies ermöglicht es uns, zusätzliche Eigenschaften zu definieren, wie z.B. [Symbol.toStringTag], während die Iterator-Hilfsmethoden auf dem zurückgegebenen Iterator verfügbar sind.
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);
}
Das Unterklassenmuster ist nützlich, wenn Sie viele benutzerdefinierte Iteratoren erstellen möchten. Wenn Sie ein vorhandenes iterierbares oder Iterator-Objekt haben, das nicht von Iterator erbt, und Sie nur die Iterator-Hilfsmethoden aufrufen möchten, können Sie Iterator.from() verwenden, um eine einmalige Iterator Instanz zu erstellen.
Spezifikationen
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-iterator-constructor> |