Iterator

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

* Some parts of this feature may have varying levels of support.

Ein Iterator-Objekt ist ein Objekt, das dem Iterator-Protokoll entspricht, indem es eine next()-Methode bereitstellt, die ein Iterator-Resultatobjekt zurückgibt. Alle eingebauten Iteratoren erben von der Iterator-Klasse. Die Iterator-Klasse stellt eine [Symbol.iterator]()-Methode bereit, die das Iterator-Objekt selbst zurückgibt, wodurch der Iterator auch iterierbar wird. Sie bietet auch einige Hilfsmethoden für die Arbeit mit Iteratoren.

Beschreibung

Die folgenden sind alle eingebauten JavaScript-Iteratoren:

Web-APIs können ebenfalls Iteratoren zurückgeben. Einige nutzen die Kern-JavaScript-Iteratoren, während andere ihre eigenen Iteratoren definieren. Zum Beispiel:

  • Array-Ähnliche Objekte wie NodeList geben einen Array-Iterator von ihren jeweiligen Methoden keys(), values(), entries() und [Symbol.iterator]() zurück.
  • Map-Ähnliche Objekte von Web-APIs wie Headers geben ihren eigenen Iteratortyp wie Headers Iterator von ihren jeweiligen Methoden keys(), values(), entries() und [Symbol.iterator]() zurück.
  • Set-Ähnliche Objekte von Web-APIs wie FontFaceSet geben ihren eigenen Iteratortyp wie FontFaceSet Iterator von ihren jeweiligen Methoden keys(), values(), entries() und [Symbol.iterator]() zurück.

Note: NodeIterator und andere alte Schnittstellen sind so benannt, entsprechen aber nicht dem Iterator-Protokoll oder dem Iterable-Protokoll.

Jeder dieser Iteratoren hat ein eigenes Prototyp-Objekt, das die next()-Methode definiert, die von dem bestimmten Iterator verwendet wird. Zum Beispiel erben alle String-Iterator-Objekte von einem versteckten Objekt StringIteratorPrototype, das eine next()-Methode hat, die diesen String durch Codepunkte iteriert. StringIteratorPrototype hat auch eine [Symbol.toStringTag]-Eigenschaft, deren Anfangswert der String "String Iterator" ist. Diese Eigenschaft wird in Object.prototype.toString() verwendet. Ähnlich haben andere Iterator-Prototypen auch ihre eigenen [Symbol.toStringTag]-Werte, die mit den oben genannten Namen übereinstimmen.

Alle diese Prototyp-Objekte erben von Iterator.prototype, welches eine [Symbol.iterator]()-Methode bereitstellt, die das Iterator-Objekt selbst zurückgibt und den Iterator somit auch iterierbar macht.

Iteratoren-Hilfsmethoden

Hinweis: Diese Methoden sind Iteratoren-Hilfen, keine Iterable-Hilfen, weil die einzige Anforderung für ein Objekt, iterierbar zu sein, das Vorhandensein einer [Symbol.iterator]()-Methode ist. Es gibt kein gemeinsames Prototyp, um diese Methoden zu installieren.

Die Iterator-Klasse selbst bietet einige Hilfsmethoden für die Arbeit mit Iteratoren. Zum Beispiel könnten Sie versucht sein, Folgendes zu tun:

js
const nameToDeposit = new Map([
  ["Anne", 1000],
  ["Bert", 1500],
  ["Carl", 2000],
]);

const totalDeposit = [...nameToDeposit.values()].reduce((a, b) => a + b);

Dies konvertiert zuerst den von Map.prototype.values() zurückgegebenen Iterator in ein Array und verwendet dann die Array.prototype.reduce()-Methode, um die Summe zu berechnen. Dies erstellt jedoch sowohl ein Zwischen-Array als auch iteriert das Array zweimal. Stattdessen können Sie die reduce()-Methode des Iterators selbst verwenden:

js
const totalDeposit = nameToDeposit.values().reduce((a, b) => a + b);

Diese Methode ist möglicherweise effizienter, insbesondere speichermäßig, da sie den Iterator nur einmal durchläuft, ohne Zwischenwerte zu merken. Iterator-Hilfsmethoden sind notwendig, um mit unendlichen Iteratoren zu arbeiten:

js
function* fibonacci() {
  let current = 1;
  let next = 1;
  while (true) {
    yield current;
    [current, next] = [next, current + next];
  }
}

const seq = fibonacci();
const firstThreeDigitTerm = seq.find((n) => n >= 100);

Sie können seq nicht in ein Array konvertieren, da es unendlich ist. Stattdessen können Sie die find()-Methode des Iterators selbst verwenden, die seq nur so weit durchläuft, wie nötig, um den ersten Wert zu finden, der die Bedingung erfüllt.

Sie werden viele Iterator-Methoden finden, die den Array-Methoden analog sind, wie:

Iterator-Methode Array-Methode
Iterator.prototype.every() Array.prototype.every()
Iterator.prototype.filter() Array.prototype.filter()
Iterator.prototype.find() Array.prototype.find()
Iterator.prototype.flatMap() Array.prototype.flatMap()
Iterator.prototype.forEach() Array.prototype.forEach()
Iterator.prototype.map() Array.prototype.map()
Iterator.prototype.reduce() Array.prototype.reduce()
Iterator.prototype.some() Array.prototype.some()

Iterator.prototype.drop() und Iterator.prototype.take() kombiniert sind in gewisser Weise analog zu Array.prototype.slice().

Iterator-Hilfeobjekte

Note: Iterator-Hilfeobjekte und Iterator-Hilfsmethoden sind zwei verschiedene Konzepte. Ein Iterator-Hilfeobjekt ist zur Laufzeit nachweisbar, während "Iterator-Hilfsmethode" nur ein Name für eine Gruppe von Methoden zur Verständnishilfe ist. Iterator-Hilfe kann sich je nach Kontext entweder auf das Objekt oder die Methode beziehen.

Unter den Iterator-Hilfsmethoden geben filter(), flatMap(), map(), drop() und take() ein neues Iterator-Hilfeobjekt zurück. Der Iterator-Helfer ist auch eine Iterator-Instanz, wodurch diese Hilfsmethoden verkettbar sind. Alle Iterator-Hilfeobjekte erben von einem gemeinsamen Prototyp-Objekt, welches das Iterator-Protokoll implementiert:

next()

Ruft die next()-Methode des zugrunde liegenden Iterators auf, wendet die Hilfsmethode auf das Ergebnis an und gibt das Ergebnis zurück.

return()

Ruft die return()-Methode des zugrunde liegenden Iterators auf und gibt das Ergebnis zurück.

Der Iterator-Helfer teilt die gleiche Datenquelle wie der zugrunde liegende Iterator, sodass das Iterieren des Iterator-Helfers auch den zugrunde liegenden Iterator iteriert. Es gibt keine Möglichkeit, einen Iterator zu "verzweigen", sodass er mehrfach iteriert werden kann.

js
const it = [1, 2, 3].values();
const it2 = it.drop(0); // Essentially a copy
console.log(it.next().value); // 1
console.log(it2.next().value); // 2
console.log(it.next().value); // 3

Richtige Iteratoren

Es gibt zwei Arten von "Iteratoren": Objekte, die dem Iterator-Protokoll entsprechen (was minimal nur das Vorhandensein einer next()-Methode erfordert), und Objekte, die von der Iterator-Klasse erben und die Hilfsmethoden nutzen können. Sie schließen sich nicht gegenseitig ein — Objekte, die von Iterator erben, werden nicht automatisch zu Iteratoren, da die Iterator-Klasse keine next()-Methode definiert. Stattdessen muss das Objekt selbst eine next()-Methode definieren. Ein richtiger Iterator ist einer, der sowohl dem Iterator-Protokoll entspricht als auch von Iterator erbt, und die meiste Software erwartet, dass Iteratoren richtige Iteratoren sind und dass Iterables richtige Iteratoren zurückgeben. Um richtige Iteratoren zu erstellen, definieren Sie eine Klasse, die von Iterator erbt, oder verwenden Sie die Iterator.from()-Methode.

js
class MyIterator extends Iterator {
  next() {
    // …
  }
}

const myIterator = Iterator.from({
  next() {
    // …
  },
});

Konstruktor

Iterator()

Soll von anderen Klassen, die Iteratoren erstellen, erweitert werden. Löst einen Fehler aus, wenn es selbst konstruiert wird.

Statische Methoden

Iterator.from()

Erstellt ein neues Iterator-Objekt aus einem Iterator oder iterierbaren Objekt.

Instanz-Eigenschaften

Diese Eigenschaften sind auf Iterator.prototype definiert und werden von allen Iterator-Instanzen geteilt.

Iterator.prototype.constructor

Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für Iterator-Instanzen ist der Anfangswert der Iterator-Konstruktor.

Iterator.prototype[Symbol.toStringTag]

Der Anfangswert der [Symbol.toStringTag]-Eigenschaft ist der String "Iterator". Diese Eigenschaft wird in Object.prototype.toString() verwendet.

Hinweis: Anders als die [Symbol.toStringTag] bei den meisten eingebauten Klassen ist das Iterator.prototype[Symbol.toStringTag] beschreibbar aus Gründen der Web-Kompatibilität.

Instanz-Methoden

Iterator.prototype.drop()

Gibt ein neues Iterator-Hilfeobjekt zurück, das die angegebene Anzahl von Elementen am Anfang dieses Iterators überspringt.

Iterator.prototype.every()

Prüft, ob alle vom Iterator produzierten Elemente den Test bestehen, der von der bereitgestellten Funktion implementiert wurde.

Iterator.prototype.filter()

Gibt ein neues Iterator-Hilfeobjekt zurück, das nur die Elemente des Iterators liefert, für die die bereitgestellte Callback-Funktion true zurückgibt.

Iterator.prototype.find()

Gibt das erste Element zurück, das von dem Iterator produziert wird und die bereitgestellte Testfunktion erfüllt. Wenn keine Werte die Testfunktion erfüllen, wird undefined zurückgegeben.

Iterator.prototype.flatMap()

Gibt ein neues Iterator-Hilfeobjekt zurück, das jedes Element im ursprünglichen Iterator durch eine Mapping-Funktion laufen lässt und die von der Mapping-Funktion zurückgegebenen Elemente (die sich in einem anderen Iterator oder iterierbaren Objekt befinden) liefert.

Iterator.prototype.forEach()

Führt eine bereitgestellte Funktion einmal für jedes vom Iterator produzierte Element aus.

Iterator.prototype.map()

Gibt ein neues Iterator-Hilfeobjekt zurück, das die Elemente des Iterators liefert, jedes durch eine Mapping-Funktion transformiert.

Iterator.prototype.reduce()

Führt eine benutzerdefinierte "Reducer"-Callback-Funktion bei jedem vom Iterator produzierten Element aus und übergibt den Rückgabewert der Berechnung des vorhergehenden Elements. Das Endergebnis des Reduzierens aller Elemente ist ein einzelner Wert.

Iterator.prototype.some()

Prüft, ob mindestens ein Element im Iterator den von der bereitgestellten Funktion implementierten Test besteht. Es gibt einen booleschen Wert zurück.

Iterator.prototype.take()

Gibt ein neues Iterator-Hilfeobjekt zurück, das die angegebene Anzahl von Elementen in diesem Iterator liefert und dann terminiert.

Iterator.prototype.toArray()

Erstellt eine neue Array-Instanz, die mit den vom Iterator gelieferten Elementen gefüllt ist.

Iterator.prototype[Symbol.iterator]()

Gibt das Iterator-Objekt selbst zurück. Dadurch können Iterator-Objekte auch iterierbar sein.

Beispiele

Verwendung eines Iterators als Iterable

Alle eingebauten Iteratoren sind auch iterierbar, sodass Sie sie in einer for...of-Schleife verwenden können:

js
const arrIterator = [1, 2, 3].values();
for (const value of arrIterator) {
  console.log(value);
}
// Logs: 1, 2, 3

Spezifikationen

Specification
ECMAScript® 2025 Language Specification
# sec-%iteratorprototype%-object

Browser-Kompatibilität

Siehe auch