Die Verarbeitung jedes Elements in einer Sammlung ist eine sehr häufige Operation, die von einfachen for- und for-each-Schleifen bis hin zu map()-, filter()- und Array-Comprehensions reicht. In JavaScript 1.7 bringen Iteratoren und Generatoren neue Iterationsmechanismen in die JavaScript-Kernsyntax ein und bieten außerdem einen Mechanismus zum Anpassen des Verhaltens von for...in- und for every-Schleifen.
Iterator
Ein Iterator ist ein Objekt, das jeweils auf ein Element in einer Sammlungssequenz zugreift und die aktuelle Position der Iteration in der Sequenz verfolgt. In JavaScript ist ein Iterator ein Objekt, das eine next()-Methode bereitstellt, die das nächste Element in der Sequenz zurückgibt. Diese Methode löst eine StopIteration-Ausnahme aus, wenn alle Elemente in der Sequenz durchlaufen wurden.
Sobald ein Iteratorobjekt erstellt wurde, kann es explizit durch wiederholten Aufruf von next() oder implizit mithilfe der for...in- und for every-Schleifen von JavaScript aufgerufen werden.
Einfache Iteratoren zum Durchlaufen von Objekten und Arrays können mit Iterator() erstellt werden:
Sobald die Initialisierung abgeschlossen ist, kann die Methode next() aufgerufen werden, um nacheinander auf die Schlüssel-Wert-Paare des Objekts zuzugreifen:
Die for…in-Schleife kann anstelle des expliziten Aufrufs der next()-Methode verwendet werden. Die Schleife wird automatisch beendet, wenn die StopIteration-Ausnahme ausgelöst wird.
Wenn Sie nur den Schlüsselwert des Objekts iterieren möchten, können Sie den zweiten Parameter mit dem Wert true an die Funktion Iterator() übergeben:
Ein Vorteil der Verwendung von Iterator() für den Zugriff auf Objekte besteht darin, dass zu Object.prototype hinzugefügte benutzerdefinierte Eigenschaften nicht im Sequenzobjekt enthalten sind.
Iterator() kann auch für Arrays verwendet werden:
Genau wie beim Durchlaufen eines Objekts führt die Übergabe von „true“ als zweiter Parameter dazu, dass die Durchquerung der Array-Index ist:
Verwenden Sie das Schlüsselwort let, um Blockvariablen innerhalb der Schleife Indizes und Werte zuzuweisen. Sie können auch die destrukturierende Zuweisung verwenden:
Deklarieren Sie einen benutzerdefinierten Iterator
Einige Objekte, die eine Sammlung von Elementen darstellen, sollten auf eine bestimmte Weise iteriert werden.
1. Die Iteration eines Objekts, das einen Bereich darstellt, sollte die im Bereich enthaltenen Zahlen nacheinander zurückgeben
2. Auf die Blattknoten eines Baums kann mit der Tiefen- oder Breitenorientierung
zugegriffen werden
3. Beim Durchlaufen eines Objekts, das die Ergebnisse einer Datenbankabfrage darstellt, sollten Zeile für Zeile zurückgegeben werden, auch wenn die gesamte Ergebnismenge noch nicht in ein einzelnes Array geladen wurde
4. Ein Iterator, der auf eine unendliche mathematische Folge (wie die Fibonacci-Folge) einwirkt, sollte Ergebnisse nacheinander zurückgeben, ohne eine Datenstruktur unendlicher Länge zu erstellen
JavaScript ermöglicht es Ihnen, benutzerdefinierte Iterationslogik zu schreiben und diese auf ein Objekt anzuwenden
Wir erstellen ein einfaches Range-Objekt, das niedrige und hohe Werte enthält:
Jetzt erstellen wir einen benutzerdefinierten Iterator, der eine Sequenz zurückgibt, die alle Ganzzahlen im Bereich enthält. Für die Iterator-Schnittstelle müssen wir eine next()-Methode bereitstellen, um das nächste Element in der Sequenz zurückzugeben oder eine StopIteration-Ausnahme auszulösen.
Unser RangeIterator wird mit einer Range-Instanz instanziiert und verwaltet eine aktuelle Eigenschaft, um die aktuelle Sequenzposition zu verfolgen.
Damit RangeIterator schließlich mit Range kombiniert werden kann, müssen wir eine spezielle __iterator__-Methode für Range hinzufügen. Es wird aufgerufen, wenn wir versuchen, über einen Bereich zu iterieren, und sollte eine RangeIterator-Instanz zurückgeben, die die Iterationslogik implementiert.
Sobald wir unseren benutzerdefinierten Iterator fertiggestellt haben, können wir über eine Bereichsinstanz iterieren:
Generatoren: eine bessere Möglichkeit, Iteratoren zu erstellen
Obwohl benutzerdefinierte Iteratoren ein nützliches Werkzeug sind, ist bei ihrer Erstellung eine sorgfältige Planung erforderlich, da ihr interner Zustand explizit beibehalten werden muss.
Der Generator bietet sehr leistungsstarke Funktionen: Er ermöglicht die Definition einer Funktion, die einen eigenen Iterationsalgorithmus enthält, und kann automatisch seinen eigenen Status beibehalten.
Generatoren sind spezielle Funktionen, die als Iteratorfabriken dienen können. Wenn eine Funktion einen oder mehrere Ertragsausdrücke enthält, wird sie als Generator bezeichnet (Anmerkung des Übersetzers: Node.js muss auch * vor dem Funktionsnamen hinzufügen, um dies anzuzeigen).
Hinweis: Nur Codeblöcke, die in