Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung von Iteratoren und Generatoren in JavaScript_Javascript-Kenntnissen

Detaillierte Erläuterung von Iteratoren und Generatoren in JavaScript_Javascript-Kenntnissen

WBOY
WBOYOriginal
2016-05-16 16:32:521460Durchsuche

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:

Code kopieren Der Code lautet wie folgt:

var lang = { name: 'JavaScript', Geburtsjahr: 1995 };
var it = Iterator(lang);

Sobald die Initialisierung abgeschlossen ist, kann die Methode next() aufgerufen werden, um nacheinander auf die Schlüssel-Wert-Paare des Objekts zuzugreifen:

Code kopieren Der Code lautet wie folgt:

var pair = it.next(); //Das Schlüssel-Wert-Paar ist ["name", "JavaScript"]
pair = it.next(); //Das Schlüssel-Wert-Paar ist ["Geburtstag", 1995]
pair = it.next(); //Eine „StopIteration“-Ausnahme wird ausgelöst

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.

Code kopieren Der Code lautet wie folgt:

var it = Iterator(lang);
für (Var-Paar darin)
Print(pair); //Jedes Mal ein [Schlüssel, Wert]-Schlüssel-Wert-Paar darin ausgeben

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:

Code kopieren Der Code lautet wie folgt:

var it = Iterator(lang, true);
for (Var-Schlüssel darin)
Print(key); //Schlüsselwert jedes Mal ausgeben

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:

Code kopieren Der Code lautet wie folgt:

var langs = ['JavaScript', 'Python', 'Haskell'];
var it = Iterator(langs);
für (Var-Paar darin)
​​​ print(pair); //Jede Iteration gibt ein [Index, Sprache]-Schlüssel-Wert-Paar aus

Genau wie beim Durchlaufen eines Objekts führt die Übergabe von „true“ als zweiter Parameter dazu, dass die Durchquerung der Array-Index ist:

Code kopieren Der Code lautet wie folgt:

var langs = ['JavaScript', 'Python', 'Haskell'];
var it = Iterator(langs, true);
für (var i darin)
​​​ print(i); //Ausgabe 0, dann 1, dann 2

Verwenden Sie das Schlüsselwort let, um Blockvariablen innerhalb der Schleife Indizes und Werte zuzuweisen. Sie können auch die destrukturierende Zuweisung verwenden:

Code kopieren Der Code lautet wie folgt:

var langs = ['JavaScript', 'Python', 'Haskell'];
var it = Iterators(langs);
für (lass [i, lang] drin)
          print(i ': ' lang); //Ausgabe „0: JavaScript“ usw.

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:

Code kopieren Der Code lautet wie folgt:

Funktionsbereich (niedrig, hoch){
This.low = niedrig;
This.high = hoch;
}

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.

Code kopieren Der Code lautet wie folgt:

Funktion RangeIterator(range){
This.range = range;
This.current = this.range.low;
}
RangeIterator.prototype.next = function(){
If (this.current > this.range.high)
          throw StopIteration;
       sonst
          return this.current ;
};

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.

Code kopieren Der Code lautet wie folgt:

Range.prototype.__iterator__ = function(){
        return new RangeIterator(this);
};

Sobald wir unseren benutzerdefinierten Iterator fertiggestellt haben, können wir über eine Bereichsinstanz iterieren:

Code kopieren Der Code lautet wie folgt:

var range = new Range(3, 5);
für (var i im Bereich)
​​​ print(i); //Ausgabe 3, dann 4, dann 5

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