Die function*-Deklaration ( Schlüsselwort function gefolgt von einem Stern) definiert eine Generatorfunktion, welche ein Generator-Objekt zurückgibt.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Eine Generatorfunktion kann auch mittels des GeneratorFunction-Konstruktors definiert werden.
Syntax
function* name([param[, param[, ... param]]]) {
statements
}
name- Der Name der Funktion.
param- Der Name eines an die Funktion zu übergebenden Arguments. Eine Funktion kann bis zu 255 Argumente haben.
statements- Die den Körper der Funktion ergebenden Anweisungen.
Beschreibung
Generatoren sind Funktionen, die verlassen und später wieder betreten werden können. Ihr Kontext (Variablenbindung) bleibt über die Wiedereintritte hinweg erhalten.
Der Aufruf einer Generatorfunktion führt ihren Körper nicht sofort aus; stattdessen wird ein Iterator-Objekt einer Funktion zurückgegeben. Wenn die next()-Methode des Iterators aufgerufen wird, wird der Körper der Generatorfunktion bis zum ersten yield-Ausdruck ausgeführt, der den vom Iterator zurückzugebenden Wert spezifiziert oder mittels yield* an eine andere Generatorfunktion weitergibt. Die Methode next() gibt ein Objekt mit einer value-Eigenschaft zurück, die den zurückgegebenen Wert enthält, und eine Eigenschaft done, die anzeigt, ob der Generator seinen letzten Wert zurückgegeben hat (boolescher Wert). Beim Aufrufen der next()-Methode mit einem Argument wird die Generatorfunktion weiter ausgeführt.
Ein return-Statement in einer Generatorfunktion sorgt dafür, dass der Generator fertig ist (Status done). Falls ein Wert zurückgegeben wird, dann wird dieser als value zurückgegeben. Anschließend wird kein weiterer Wert mehr zurückgegeben.
Beispiele
Einfaches Beispiel
function* idMaker(){
var index = 0;
while(index < index+1)
yield index++;
}
var gen = idMaker();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ...
Beispiel mit yield*
function* anotherGenerator(i) {
yield i + 1;
yield i + 2;
yield i + 3;
}
function* generator(i) {
yield i;
yield* anotherGenerator(i);
yield i + 10;
}
var gen = generator(10);
console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
console.log(gen.next().value); // 20
Übergeben von Argumenten in Generatoren
function* logGenerator() {
console.log(0);
console.log(1, yield);
console.log(2, yield);
console.log(3, yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next(); // 0
gen.next('pretzel'); // 1 pretzel
gen.next('california'); // 2 california
gen.next('mayonnaise'); // 3 mayonnaise
Return Statement in einem Generator
function* yieldAndReturn() {
yield "Y";
return "R";
yield "unreachable";
}
var gen = yieldAndReturn()
console.log(gen.next()); // { value: "Y", done: false }
console.log(gen.next()); // { value: "R", done: true }
console.log(gen.next()); // { value: undefined, done: true }
Generatoren haben keinen Konstruktor
function* f() {}
var obj = new f; // throws "TypeError: f ist kein Konstruktor"
Spezifikationen
| Spezifikation | Status | Kommentar |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) Die Definition von 'function*' in dieser Spezifikation. |
Standard | Initiale Definition. |
| ECMAScript 2016 (ECMA-262) Die Definition von 'function*' in dieser Spezifikation. |
Standard | Änderung, dass Generatoren nicht über [[Construct]] trap verfügen und eine Ausnahme bei der Verwendung von new erzeugen. |
| ECMAScript Latest Draft (ECMA-262) Die Definition von 'function*' in dieser Spezifikation. |
Entwurf |
Browserkompatibilität
| Desktop | Mobile | Server | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
function* | Chrome Vollständige Unterstützung 39 | Edge Vollständige Unterstützung 13 | Firefox Vollständige Unterstützung 26 | IE Keine Unterstützung Nein | Opera Vollständige Unterstützung 26 | Safari Vollständige Unterstützung 10 | WebView Android Vollständige Unterstützung Ja | Chrome Android Vollständige Unterstützung 39 | Firefox Android Vollständige Unterstützung 26 | Opera Android Vollständige Unterstützung Ja | Safari iOS Vollständige Unterstützung 10 | Samsung Internet Android Vollständige Unterstützung 4.0 | nodejs
Vollständige Unterstützung
4.0.0
|
IteratorResult object instead of throwing | Chrome Vollständige Unterstützung 49 | Edge Vollständige Unterstützung 13 | Firefox Vollständige Unterstützung 29 | IE Keine Unterstützung Nein | Opera Vollständige Unterstützung Ja | Safari Vollständige Unterstützung Ja | WebView Android Vollständige Unterstützung Ja | Chrome Android Vollständige Unterstützung 49 | Firefox Android Vollständige Unterstützung 29 | Opera Android Vollständige Unterstützung Ja | Safari iOS Vollständige Unterstützung Ja | Samsung Internet Android Vollständige Unterstützung Ja | nodejs Vollständige Unterstützung Ja |
Not constructable with new (ES2016) | Chrome Vollständige Unterstützung 50 | Edge Vollständige Unterstützung 13 | Firefox Vollständige Unterstützung 43 | IE Keine Unterstützung Nein | Opera Vollständige Unterstützung 37 | Safari Vollständige Unterstützung 10 | WebView Android Vollständige Unterstützung 50 | Chrome Android Vollständige Unterstützung 50 | Firefox Android Vollständige Unterstützung 43 | Opera Android Vollständige Unterstützung 37 | Safari iOS Vollständige Unterstützung 10 | Samsung Internet Android Vollständige Unterstützung 5.0 | nodejs Vollständige Unterstützung Ja |
| Trailing comma in parameters | Chrome Vollständige Unterstützung 58 | Edge Vollständige Unterstützung 14 | Firefox Vollständige Unterstützung 52 | IE Keine Unterstützung Nein | Opera Vollständige Unterstützung 45 | Safari ? | WebView Android Vollständige Unterstützung 58 | Chrome Android Vollständige Unterstützung 58 | Firefox Android Vollständige Unterstützung 52 | Opera Android Vollständige Unterstützung 43 | Safari iOS ? | Samsung Internet Android Vollständige Unterstützung 7.0 | nodejs Vollständige Unterstützung 8.0.0 |
Legende
- Vollständige Unterstützung
- Vollständige Unterstützung
- Keine Unterstützung
- Keine Unterstützung
- Kompatibilität unbekannt
- Kompatibilität unbekannt
- Benutzer muss dieses Feature explizit aktivieren.
- Benutzer muss dieses Feature explizit aktivieren.
Firefox-spezifische Hinweise
Generatoren und Iteratoren in Firefox-Versionen vor 26
Ältere Firefox-Versionen implementierten eine ältere Version des Generatorenentwurfs. In den älteren Versionen wurden Generatoren, neben anderen Abweichungen, mit dem normalen Schlüsselwort function (ohne den Stern) definiert. Siehe veraltete Generatorfunktion für weitere Informationen.
IteratorResult-Objekt zurückgegeben anstatt Ausnahme erzeugt
Beginnend mit Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26) erzeugt die ausgeführte Generatorfunktion keine TypeError "generator has already finished"-Ausnahme mehr. Stattdessen gibt sie ein IteratorResult-Objekt mit { value: undefined, done: true } (Bug 958951) zurück.
Siehe auch
function* expressionGeneratorFunctionObjekt- Das Iteratorprotokol
yieldyield*Functionobjectfunction declarationfunction expressionFunctions and function scope- Andere Quellen im Web:
- Regenerator an ES2015 generator compiler to ES5
- Forbes Lindesay: Promises and Generators: control flow utopia -- JSConf EU 2013
- Hemanth.HM: The New gen of *gen(){}
- Task.js