Was ist "Funktion *" in JavaScript?

243

Auf dieser Seite habe ich einen neuen JavaScript-Funktionstyp gefunden:

// NOTE: "function*" is not supported yet in Firefox.
// Remove the asterisk in order for this code to work in Firefox 13 

function* fibonacci() { // !!! this is the interesting line !!!
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

Ich weiß schon , was yield, letund [?,?]=[?,?]zu tun , aber keine Ahnung, was das function*gemeint ist , zu sein. Was ist es?

PS: Probieren Sie Google nicht aus. Es ist unmöglich , nach Ausdrücken mit Sternchen zu suchen ( sie werden als Platzhalter verwendet ).

Zeichenfolge QNA
quelle
4
Der Kommentar im Beispiel ist mittlerweile ziemlich alt. Die function*Syntax wird in Firefox seit Version 26 unterstützt: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… *. Ältere Versionen verwendeten eine andere Syntax.
Nickolay
39
Suchen Sie in Bezug auf Google einfach nach "Funktionsstern" oder "Funktionsstern". So habe ich diese Frage gefunden;).
Tryse
2
Sieht so *aus, als wäre der Link von @Nickolay entfernt worden. Hier ist ein Link direkt zu function*bei MDN . Sicher genug, "grundlegende" Unterstützung seit v26 .
Ruffin
Ein weiterer MDN-Link (den ich übrigens auf der von OP verlinkten MDN-Seite gefunden habe) : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
BlueRaja - Danny Pflughoeft
Ein weiterer nützlicher MDN-Link: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… *
Logan

Antworten:

199

Es ist eine Generatorfunktion .

Generatoren sind Funktionen, die beendet und später wieder eingegeben werden können. Ihr Kontext (variable Bindungen) wird über alle Eingänge hinweg gespeichert.

Das Aufrufen einer Generatorfunktion führt ihren Körper nicht sofort aus. Stattdessen wird ein Iteratorobjekt für die Funktion zurückgegeben. Wenn die next()Methode des Iterators aufgerufen wird, wird der Hauptteil der Generatorfunktion bis zum ersten yieldAusdruck ausgeführt, der den Wert angibt, der vom Iterator zurückgegeben oder mit yield*einer anderen Generatorfunktion delegiert werden soll.


Historischer Hinweis:

Es ist eine vorgeschlagene Syntax für EcmaScript.next.

Dave Herman von Mozilla hielt einen Vortrag über EcmaScript.next . Um 30:15 spricht er über Generatoren.

Zuvor erklärte er, wie Mozilla vorgeschlagene Sprachänderungen experimentell umsetzt, um das Komitee zu steuern. Dave arbeitet eng mit Brendan Eich, Mozillas CTO (glaube ich) und dem ursprünglichen JavaScript-Designer zusammen.

Weitere Informationen finden Sie im Wiki der EcmaScript-Arbeitsgruppe: http://wiki.ecmascript.org/doku.php?id=harmony:generators

Die Arbeitsgruppe (TC-39) ist sich allgemein einig, dass EcmaScript.next einen Vorschlag für einen Generator-Iterator enthalten sollte, der jedoch nicht endgültig ist.

Sie sollten sich nicht darauf verlassen, dass dies ohne Änderungen in der nächsten Version der Sprache angezeigt wird, und selbst wenn es sich nicht ändert, wird es wahrscheinlich für eine Weile nicht in anderen Browsern angezeigt.

Überblick

Erstklassige Coroutinen, dargestellt als Objekte, die suspendierte Ausführungskontexte einschließen (dh Funktionsaktivierungen). Stand der Technik: Python, Icon, Lua, Scheme, Smalltalk.

Beispiele

Die "unendliche" Folge von Fibonacci-Zahlen (ungeachtet des Verhaltens um 2 53 ):

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        [prev, curr] = [curr, prev + curr];
        yield curr;
    }
}

Generatoren können in Schleifen durchlaufen werden:

for (n of fibonacci()) {
    // truncate the sequence at 1000
    if (n > 1000)
        break;
    print(n);
}

Generatoren sind Iteratoren:

let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8
Mike Samuel
quelle
7
Follow-up: Was macht eine for-Schleife ohne Parameter ( for(;;))? Warum in diesem Zusammenhang verwenden?
Fergie
13
@Fergie, for(;;)ist das gleiche wie while (true). Es wird in diesem Zusammenhang verwendet, da die Fibonacci-Sequenz eine unbegrenzte Sequenz ist.
Mike Samuel
5
Stand der Technik: C # -Ausbeute?
Dave Van den Eynde
3
@ DaveVandenEynde, Stand der Technik: Python-Ausbeute. Stand der Technik: CLU und Icon.
Mike Samuel
52

Es ist eine Generatorfunktion - und das stand auf der Seite, die Sie zitieren, in dem Kommentar, den Sie durch "Dies ist die interessante Zeile" ersetzt haben ...

Grundsätzlich ist es eine Möglichkeit, Sequenzen programmgesteuert anzugeben, damit sie weitergegeben und Elemente über den Index aufgerufen werden können, ohne zuvor die gesamte Sequenz (möglicherweise unendlich groß) berechnen zu müssen.

Michael Borgwardt
quelle
10
"Zugriff durch Index, ohne die gesamte Sequenz berechnen zu müssen" ist möglicherweise die hilfreichste Erklärung für Generatoren, auf die ich bisher gestoßen bin. Ich konnte sehen, dass dies in einer App verwendet wurde, anstatt es vorher nur theoretisch zu verstehen.
Wes
11

Der function*Typ scheint als Generatorfunktion für Prozesse zu fungieren, die iteriert werden können. C # hat eine Funktion wie diese mit "Yield Return", siehe 1 und siehe 2

Im Wesentlichen gibt dies jeden Wert einzeln an das zurück, was diese Funktion iteriert, weshalb der Anwendungsfall ihn in einer foreach-Stilschleife anzeigt.

ungültiger Satzbau
quelle