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, indem es eine next()-Methode bereitstellt, die ein Iterator-Ergebnisobjekt 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 und den Iterator auch iterierbar macht. Sie bietet auch einige Hilfsmethoden für die Arbeit mit Iteratoren.
Beschreibung
Folgende sind alle eingebauten JavaScript-Iteratoren:
- Der Array-Iterator wird zurückgegeben von
Array.prototype.values(),Array.prototype.keys(),Array.prototype.entries(),Array.prototype[Symbol.iterator](),TypedArray.prototype.values(),TypedArray.prototype.keys(),TypedArray.prototype.entries(),TypedArray.prototype[Symbol.iterator]()undarguments[Symbol.iterator](). - Der String-Iterator wird zurückgegeben von
String.prototype[Symbol.iterator](). - Der Map-Iterator wird zurückgegeben von
Map.prototype.values(),Map.prototype.keys(),Map.prototype.entries()undMap.prototype[Symbol.iterator](). - Der Set-Iterator wird zurückgegeben von
Set.prototype.values(),Set.prototype.keys(),Set.prototype.entries()undSet.prototype[Symbol.iterator](). - Der RegExp String-Iterator wird zurückgegeben von
RegExp.prototype[Symbol.matchAll]()undString.prototype.matchAll(). - Das
Generator-Objekt wird zurückgegeben von Generatorfunktionen. - Der Segments-Iterator wird von der
[Symbol.iterator]()-Methode desSegments-Objekts zurückgegeben, welches vonIntl.Segmenter.prototype.segment()zurückgegeben wird. - Der Iterator Helper, zurückgegeben von Iterator-Hilfsmethoden wie
Iterator.prototype.filter()undIterator.prototype.map().
Web-APIs können ebenfalls Iteratoren zurückgeben. Einige nutzen Kern-JavaScript-Iteratoren, während andere eigene Iteratoren definieren. Zum Beispiel:
- Array-ähnliche Objekte wie
NodeListgeben einen Array-Iterator von ihren jeweiligen Methodenkeys(),values(),entries()und[Symbol.iterator]()zurück. - Map-ähnliche Objekte von Web-APIs wie
Headersgeben ihre eigenen Iterator-Typen wie Headers Iterator von ihren jeweiligen Methodenkeys(),values(),entries()und[Symbol.iterator]()zurück. - Set-ähnliche Objekte von Web-APIs wie
FontFaceSetgeben ihre eigenen Iterator-Typen wie FontFaceSet Iterator von ihren jeweiligen Methodenkeys(),values(),entries()und[Symbol.iterator]()zurück.
Hinweis:
NodeIterator und andere alte Schnittstellen sind zwar so benannt, entsprechen aber weder dem Iterator-Protokoll noch dem iterierbaren Protokoll.
Jeder dieser Iteratoren hat ein eigenes Prototypobjekt, das die next()-Methode definiert, die von dem spezifischen Iterator verwendet wird. Zum Beispiel erben alle String-Iterator-Objekte von einem versteckten Objekt StringIteratorPrototype, welches eine next()-Methode hat, die diesen String in Codepunkten durchläuft. StringIteratorPrototype hat auch eine [Symbol.toStringTag]-Eigenschaft, deren Anfangswert der String "String Iterator" ist. Diese Eigenschaft wird in Object.prototype.toString() verwendet. Ähnlich haben auch andere Iterator-Prototypen ihre eigenen [Symbol.toStringTag]-Werte, die denselben Namen wie oben angegeben haben.
Alle diese Prototypobjekte erben von Iterator.prototype, welches eine [Symbol.iterator]()-Methode bereitstellt, die das Iterator-Objekt selbst zurückgibt, was den Iterator auch iterierbar macht.
Iterator-Hilfsmethoden
Hinweis:
Diese Methoden sind Iterator-Hilfen, keine iterierbaren Hilfen, weil die einzige Voraussetzung dafür, dass ein Objekt iterierbar ist, die Präsenz einer [Symbol.iterator]()-Methode ist. Es gibt kein gemeinsames Prototypobjekt, an dem diese Methoden installiert werden können.
Die Iterator-Klasse selbst bietet einige Hilfsmethoden für die Arbeit mit Iteratoren. Zum Beispiel könnten Sie versucht sein, Folgendes zu tun:
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 gleichzeitig ein Zwischen-Array und durchläuft das Array zweimal. Stattdessen können Sie die reduce()-Methode des Iterators selbst verwenden:
const totalDeposit = nameToDeposit.values().reduce((a, b) => a + b);
Diese Methode kann effizienter sein, insbesondere speichersparend, da sie den Iterator nur einmal durchläuft, ohne zwischengespeicherte Werte zu merken. Iterator-Hilfsmethoden sind notwendig, um mit unendlichen Iteratoren zu arbeiten:
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, die seq nur so weit iteriert, wie notwendig, um den ersten Wert zu finden, der die Bedingung erfüllt.
Sie finden viele Iterator-Methoden analog zu Array-Methoden, wie z.B.:
Iterator.prototype.drop() und Iterator.prototype.take() zusammen sind einigermaßen analog zu Array.prototype.slice().
Iterator-Helferobjekte
Hinweis: Iterator-Helferobjekte und Iterator-Hilfsmethoden sind zwei verschiedene Konzepte. Ein Iterator-Helferobjekt ist zur Laufzeit feststellbar, während "Iterator-Hilfsmethode" nur ein Name für eine Gruppe von Methoden zur Verständnishilfe ist. Iterator Helper 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-Helferobjekt zurück. Der Iterator-Helfer ist ebenfalls eine Iterator-Instanz, wodurch diese Hilfsmethoden verkettbar sind. Alle Iterator-Helferobjekte 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.
Der Iterator-Helfer teilt dieselbe 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", um ihn mehrfach iterierbar zu machen.
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 im Minimum nur die Präsenz einer next()-Methode erfordert), und Objekte, die von der Iterator-Klasse erben und die Hilfsmethoden nutzen können. Diese bedingen einander nicht – 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 meisten Codes erwarten, dass Iteratoren richtige Iteratoren sind und Iterierbare richtige Iteratoren zurückgeben. Um richtige Iteratoren zu erstellen, definieren Sie eine Klasse, die von Iterator erweitert wird, oder verwenden Sie die Iterator.from()-Methode.
class MyIterator extends Iterator {
next() {
// …
}
}
const myIterator = Iterator.from({
next() {
// …
},
});
Konstruktor
Iterator()-
Soll von anderen Klassen, die Iteratoren erstellen, erweitert werden. Wirft einen Fehler, wenn alleinstehend konstruiert.
Statische Methoden
Iterator.concat()-
Erstellt ein neues
Iterator-Objekt aus einer Liste iterierbarer Objekte. Der neue Iterator liefert die Werte aus jedem der Eingabeiterables nacheinander. Iterator.from()-
Erstellt ein neues
Iterator-Objekt aus einem Iterator oder einem iterierbaren Objekt. Iterator.zip()-
Erstellt ein neues
Iterator-Objekt, das Elemente aus mehreren iterierbaren Objekten aggregiert, indem Arrays mit Elementen an derselben Position geliefert werden. Iterator.zipKeyed()-
Erstellt ein neues
Iterator-Objekt, das Elemente aus mehreren iterierbaren Objekten aggregiert, indem Objekte mit Elementen an derselben Position und mit den durch die Eingabe festgelegten Schlüsseln geliefert werden.
Instanzeigenschaften
Diese Eigenschaften sind auf Iterator.prototype definiert und werden von allen Iterator-Instanzen gemeinsam verwendet.
Iterator.prototype.constructor-
Die Konstruktorfunktion, die das Instanzobjekt erstellt hat. Für
Iterator-Instanzen ist der Anfangswert derIterator-Konstruktor. Iterator.prototype[Symbol.toStringTag]-
Der Anfangswert der
[Symbol.toStringTag]-Eigenschaft ist der String"Iterator". Diese Eigenschaft wird inObject.prototype.toString()verwendet.Hinweis: Im Gegensatz zu
[Symbol.toStringTag]in den meisten eingebauten Klassen istIterator.prototype[Symbol.toStringTag]aus Gründen der Webkompatibilität schreibbar.
Instanzmethoden
Iterator.prototype.drop()-
Gibt ein neues Iterator-Helferobjekt zurück, das die angegebene Anzahl von Elementen am Anfang dieses Iterators überspringt.
Iterator.prototype.every()-
Gibt
falsezurück, wenn ein Element gefunden wird, das die angegebene Testfunktion nicht erfüllt. Andernfalls, wenn der Iterator ohne ein solches Element erschöpft ist, gibt ertruezurück. Iterator.prototype.filter()-
Gibt ein neues Iterator-Helferobjekt zurück, das nur diejenigen Elemente des Iterators liefert, für die die angegebene Callback-Funktion
truezurückgibt. Iterator.prototype.find()-
Gibt das erste vom Iterator produzierte Element zurück, das die angegebene Testfunktion erfüllt. Wenn keine Werte die Testfunktion erfüllen, wird
undefinedzurückgegeben. Iterator.prototype.flatMap()-
Gibt ein neues Iterator-Helferobjekt zurück, das jedes Element im ursprünglichen Iterator nimmt, durch eine Mapping-Funktion laufen lässt und die durch die Mapping-Funktion zurückgegebenen Elemente (die in einem anderen Iterator oder iterierbaren Objekt enthalten sind) liefert.
Iterator.prototype.forEach()-
Führt eine angegebene Funktion einmal für jedes vom Iterator produzierte Element aus.
Iterator.prototype.includes()-
Gibt
truezurück, wenn ein vom Iterator produziertes Element dem angegebenen Wert entspricht. Andernfalls, wenn der Iterator ohne ein solches Element erschöpft ist, gibt erfalsezurück. Iterator.prototype.join()-
Gibt einen String zurück, der die Verkettung aller vom Iterator produzierten Elemente ist, getrennt durch Kommata oder einen angegebenen Trennzeichen-String.
Iterator.prototype.map()-
Gibt ein neues Iterator-Helferobjekt zurück, das Elemente des Iterators liefert, die jeweils durch eine Mapping-Funktion transformiert wurden.
Iterator.prototype.reduce()-
Führt eine benutzerdefinierte "Reducer"-Callback-Funktion auf jedes vom Iterator produzierte Element aus, wobei der Rückgabewert der Berechnung des vorhergehenden Elements übergeben wird. Das Endergebnis der Ausführung des Reducers über alle Elemente ist ein einzelner Wert.
Iterator.prototype.some()-
Gibt
truezurück, wenn ein Element gefunden wird, das die angegebene Testfunktion erfüllt. Andernfalls, wenn der Iterator ohne ein solches Element erschöpft ist, gibt erfalsezurück. Iterator.prototype.take()-
Gibt ein neues Iterator-Helferobjekt zurück, das die angegebene Anzahl von Elementen in diesem Iterator liefert und dann beendet.
Iterator.prototype.toArray()-
Erstellt eine neue
Array-Instanz, die mit den vom Iterator gelieferten Elementen gefüllt ist. Iterator.prototype[Symbol.dispose]()-
Ruft die
return()-Methode vonthisauf, falls sie existiert. Dies implementiert das Disposable-Protokoll und erlaubt es, entsorgt zu werden, wenn es mitusingoderawait usingverwendet wird. Iterator.prototype[Symbol.iterator]()-
Gibt das Iterator-Objekt selbst zurück. Dies erlaubt es Iterator-Objekten, auch iterierbar zu sein.
Beispiele
>Verwendung eines Iterators als Iterierbares
Alle eingebauten Iteratoren sind auch iterierbar, sodass Sie sie in einer for...of-Schleife verwenden können:
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> |