Iterator - JavaScript | MDN

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

Baseline
Weitgehend verfügbar
*

Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit September 2016 browserübergreifend verfügbar.

* Einige Teile dieser Funktion werden möglicherweise unterschiedlich gut unterstützt.

>

Ein Iterator-Objekt ist ein Objekt, das dem Iterator-Protokoll entspricht: Es stellt eine next()-Methode bereit, die ein Iterator-Ergebnisobjekt zurückgibt. Alle integrierten Iteratoren erben von der Iterator-Klasse. Die Iterator-Klasse stellt eine [Symbol.iterator]()-Methode bereit, die das Iterator-Objekt selbst zurückgibt. Dadurch ist der Iterator auch iterierbar. Außerdem stellt die Klasse einige Hilfsmethoden für die Arbeit mit Iteratoren bereit.

Beschreibung

Die folgenden Iteratoren sind in JavaScript integriert:

Auch Web-APIs können Iteratoren zurückgeben. Einige verwenden die grundlegenden JavaScript-Iteratoren wieder, während andere eigene Iteratoren definieren. Zum Beispiel:

  • Array-ähnliche Objekte wie NodeList geben über ihre jeweiligen Methoden keys(), values(), entries() und [Symbol.iterator]() einen Array Iterator zurück.
  • Map-ähnliche Objekte aus Web-APIs wie Headers geben über ihre jeweiligen Methoden keys(), values(), entries() und [Symbol.iterator]() einen eigenen Iterator-Typ wie Headers Iterator zurück.
  • Set-ähnliche Objekte aus Web-APIs wie FontFaceSet geben über ihre jeweiligen Methoden keys(), values(), entries() und [Symbol.iterator]() einen eigenen Iterator-Typ wie FontFaceSet Iterator zurück.

Hinweis: NodeIterator und andere ältere Schnittstellen tragen zwar entsprechende Namen, entsprechen aber weder dem Iterator-Protokoll noch dem Iterable-Protokoll.

Jeder dieser Iteratoren hat ein eigenes Prototypobjekt, das die für den jeweiligen Iterator verwendete next()-Methode definiert. Beispielsweise erben alle String-Iterator-Objekte von einem verborgenen Objekt namens StringIteratorPrototype, dessen next()-Methode den String nach Codepunkten durchläuft. StringIteratorPrototype besitzt außerdem eine [Symbol.toStringTag]-Eigenschaft, deren Anfangswert der String "String Iterator" ist. Diese Eigenschaft wird in Object.prototype.toString() verwendet. Entsprechend haben auch die anderen Iterator-Prototypen eigene [Symbol.toStringTag]-Werte, die den oben genannten Namen entsprechen.

Alle diese Prototypobjekte erben von Iterator.prototype. Dieser Prototyp stellt eine [Symbol.iterator]()-Methode bereit, die das Iterator-Objekt selbst zurückgibt. Dadurch ist der Iterator auch iterierbar.

Iterator-Hilfsmethoden

Hinweis: Diese Methoden sind Hilfsmethoden für Iteratoren, nicht für Iterables: Damit ein Objekt iterierbar ist, muss es lediglich eine [Symbol.iterator]()-Methode besitzen. Es gibt keinen gemeinsamen Prototyp, auf dem diese Methoden installiert werden könnten.

Die Iterator-Klasse selbst stellt einige Hilfsmethoden für die Arbeit mit Iteratoren bereit. Beispielsweise 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);

Dabei wird der von Map.prototype.values() zurückgegebene Iterator zuerst in ein Array umgewandelt. Anschließend wird mit der Methode Array.prototype.reduce() die Summe berechnet. Dadurch wird jedoch ein temporäres Array erstellt und das Array zweimal durchlaufen. Stattdessen können Sie die reduce()-Methode des Iterators selbst verwenden:

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

Diese Methode kann insbesondere hinsichtlich des Speicherverbrauchs effizienter sein, da sie den Iterator nur einmal durchläuft, ohne Zwischenwerte zu speichern. Iterator-Hilfsmethoden sind erforderlich, 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 umwandeln, da es unendlich ist. Stattdessen können Sie die find()-Methode des Iterators selbst verwenden. Sie durchläuft seq nur so weit, wie es nötig ist, um den ersten Wert zu finden, der die Bedingung erfüllt.

Viele Iterator-Methoden haben Entsprechungen bei Array-Methoden, zum Beispiel:

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.includes() Array.prototype.includes()
Iterator.prototype.join() Array.prototype.join()
Iterator.prototype.map() Array.prototype.map()
Iterator.prototype.reduce() Array.prototype.reduce()
Iterator.prototype.some() Array.prototype.some()

Die Kombination aus Iterator.prototype.drop() und Iterator.prototype.take() entspricht in gewisser Weise Array.prototype.slice().

Iterator-Hilfsobjekte

Hinweis: Iterator-Hilfsobjekte und Iterator-Hilfsmethoden sind zwei unterschiedliche Konzepte. Ein Iterator-Hilfsobjekt lässt sich zur Laufzeit erkennen, während „Iterator-Hilfsmethode“ lediglich eine Bezeichnung für eine Gruppe von Methoden zum besseren Verständnis ist. Iterator Helper kann sich je nach Kontext auf das Objekt oder die Methode beziehen.

Von den Iterator-Hilfsmethoden geben filter(), flatMap(), map(), drop() und take() jeweils ein neues Iterator Helper-Objekt zurück. Dieses ist ebenfalls eine Iterator-Instanz, sodass sich die Hilfsmethoden verketten lassen. Alle Iterator-Hilfsobjekte erben von einem gemeinsamen Prototypobjekt, das 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.

Das Iterator-Hilfsobjekt nutzt dieselbe Datenquelle wie der zugrunde liegende Iterator. Wenn das Hilfsobjekt durchlaufen wird, wird daher auch der zugrunde liegende Iterator durchlaufen. Es gibt keine Möglichkeit, einen Iterator zu „verzweigen“, um ihn mehrfach durchlaufen zu können.

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

Vollwertige Iteratoren

Es gibt zwei Arten von „Iteratoren“: Objekte, die dem Iterator-Protokoll entsprechen (wofür mindestens eine next()-Methode vorhanden sein muss), und Objekte, die von der Iterator-Klasse erben und damit über die Hilfsmethoden verfügen. Die eine Eigenschaft folgt nicht aus der anderen: Objekte, die von Iterator erben, sind nicht automatisch Iteratoren, da die Iterator-Klasse keine next()-Methode definiert. Das Objekt muss daher selbst eine next()-Methode definieren. Ein vollwertiger Iterator entspricht sowohl dem Iterator-Protokoll als auch der Vererbung von Iterator. Der meiste Code erwartet, dass Iteratoren vollwertige Iteratoren sind und dass Iterables vollwertige Iteratoren zurückgeben. Um vollwertige Iteratoren zu erstellen, definieren Sie eine Klasse, die Iterator erweitert, oder verwenden Sie die Methode Iterator.from().

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

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

Konstruktor

Iterator()

Dafür vorgesehen, von anderen Klassen erweitert zu werden, die Iteratoren erstellen. Bei direkter Instanziierung wird ein Fehler ausgelöst.

Statische Methoden

Iterator.concat()

Erstellt aus einer Liste iterierbarer Objekte ein neues Iterator-Objekt. Der neue Iterator gibt die Werte der übergebenen Iterables nacheinander aus.

Iterator.from()

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

Iterator.zip()

Erstellt ein neues Iterator-Objekt, das Elemente aus mehreren iterierbaren Objekten zusammenfasst. Es gibt Arrays aus, die jeweils die Elemente an derselben Position enthalten.

Iterator.zipKeyed()

Erstellt ein neues Iterator-Objekt, das Elemente aus mehreren iterierbaren Objekten zusammenfasst. Es gibt Objekte aus, die jeweils die Elemente an derselben Position enthalten und deren Schlüssel durch die Eingabe festgelegt werden.

Instanzeigenschaften

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

Iterator.prototype.constructor

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

Iterator.prototype[Symbol.toStringTag]

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

Hinweis: Anders als [Symbol.toStringTag] bei den meisten integrierten Klassen ist Iterator.prototype[Symbol.toStringTag] aus Gründen der Webkompatibilität beschreibbar.

Instanzmethoden

Iterator.prototype.chunks()

Gibt ein neues Iterator-Hilfsobjekt zurück, das die Elemente des ursprünglichen Iterators in aufeinanderfolgende Array-Blöcke aufteilt. Bei jedem Iterationsschritt entnimmt das Hilfsobjekt dem zugrunde liegenden Iterator die angegebene Anzahl von Elementen und gibt sie gemeinsam aus.

Iterator.prototype.drop()

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

Iterator.prototype.every()

Gibt false zurück, wenn ein Element gefunden wird, das die angegebene Prüffunktion nicht erfüllt. Andernfalls gibt die Methode true zurück, wenn der Iterator erschöpft ist, ohne dass ein solches Element gefunden wurde.

Iterator.prototype.filter()

Gibt ein neues Iterator-Hilfsobjekt zurück, das nur die Elemente des Iterators ausgibt, für die die angegebene Callback-Funktion true zurückgibt.

Iterator.prototype.find()

Gibt das erste vom Iterator ausgegebene Element zurück, das die angegebene Prüffunktion erfüllt. Wenn kein Wert die Prüffunktion erfüllt, wird undefined zurückgegeben.

Iterator.prototype.flatMap()

Gibt ein neues Iterator-Hilfsobjekt zurück, das jedes Element des ursprünglichen Iterators an eine Mapping-Funktion übergibt und die von ihr zurückgegebenen Elemente ausgibt. Diese befinden sich in einem anderen Iterator oder Iterable.

Iterator.prototype.forEach()

Führt eine angegebene Funktion einmal für jedes vom Iterator ausgegebene Element aus.

Iterator.prototype.includes()

Gibt true zurück, wenn ein vom Iterator ausgegebenes Element dem angegebenen Wert entspricht. Andernfalls gibt die Methode false zurück, wenn der Iterator erschöpft ist, ohne dass ein solches Element gefunden wurde.

Iterator.prototype.join()

Gibt einen String zurück, der aus der Verkettung aller vom Iterator ausgegebenen Elemente besteht. Die Elemente werden durch Kommas oder einen angegebenen Trennstring getrennt.

Iterator.prototype.map()

Gibt ein neues Iterator-Hilfsobjekt zurück, das die Elemente des Iterators ausgibt, nachdem sie jeweils durch eine Mapping-Funktion transformiert wurden.

Iterator.prototype.reduce()

Führt für jedes vom Iterator ausgegebene Element eine vom Benutzer bereitgestellte „Reducer“-Callback-Funktion aus und übergibt dabei den Rückgabewert der Berechnung für das vorherige Element. Das Endergebnis der Anwendung des Reducers auf alle Elemente ist ein einzelner Wert.

Iterator.prototype.some()

Gibt true zurück, wenn ein Element gefunden wird, das die angegebene Prüffunktion erfüllt. Andernfalls gibt die Methode false zurück, wenn der Iterator erschöpft ist, ohne dass ein solches Element gefunden wurde.

Iterator.prototype.take()

Gibt ein neues Iterator-Hilfsobjekt zurück, das die angegebene Anzahl von Elementen dieses Iterators ausgibt und dann endet.

Iterator.prototype.toArray()

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

Iterator.prototype.windows()

Gibt ein neues Iterator-Hilfsobjekt zurück, das ein gleitendes Fenster von Elementen ausgibt. Bei jedem Iterationsschritt gibt das Hilfsobjekt ein Array aus, bei dem das erste Element des vorherigen Schritts entfernt und das nächste Element des ursprünglichen Iterators hinzugefügt wurde.

Iterator.prototype[Symbol.dispose]()

Ruft die return()-Methode von this auf, sofern sie vorhanden ist. Dadurch wird das Disposable-Protokoll implementiert und eine Bereinigung ermöglicht, wenn der Iterator mit using oder await using verwendet wird.

Iterator.prototype[Symbol.iterator]()

Gibt das Iterator-Objekt selbst zurück. Dadurch sind Iterator-Objekte auch iterierbar.

Beispiele

>

Einen Iterator als Iterable verwenden

Alle integrierten Iteratoren sind auch iterierbar. Sie können sie daher in einer for...of-Schleife verwenden:

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

Spezifikationen

Spezifikation
ECMAScript® 2027 Language Specification>
# sec-iterator-objects>

Browser-Kompatibilität

Siehe auch