Deklaracja function* (Słowo kluczowe function przed gwiazdką) definiuje funkcję generatora, która zwraca obiekt Generator.
Możesz także zdefinować funkcje generatora używając konstruktora GeneratorFunction oraz function* expression.
Składnia
function* name([param[, param[, ... param]]]) {
statements
}
name- Nazwa funkcji.
param- Nazwa argumentu przekazywanego do funkcji. Funkcja może posiadać maksymalnie 255 argumentów.
statements- Polecenia wypełniające ciało funkcji.
Opis
Generatory są specyficznym rodzajem funkcji, która może być zatrzymywana i wznawiana. Pomiędzy kolejnymi wznowieniami zachowany jest kontekst (variable bindings).
Wywołanie funkcji generatora nie wykonuje poleceń w niej zawartych od razu; Zamiast tego, zwracany jest obiekt iteratora. Dopiero kiedy na iteratorze wywoływana jest metoda next() wykonywane jest ciało funkcji, do momentu wystąpienia pierwszego wyrażenia yield. yield Określa jaka wartość zostanie zwrócona z generatora lub, jeśli użyto yield*, wskazuje na kolejny do wywołania generator. Metoda next() zwraca obiekt z właściwością value zawierającą zwróconą przez yield wartość oraz właściowść done , która wskazuje czy generator zwórcił już wartość ostatniego yield. Wywołanie metody next() z argumentem, będzie wznawiało wykonywanie generatora za miejscem gdzie występował yield wstrzymujący generator.
Przykłady
Prosty przykład
function* idMaker() {
var index = 0;
while (index < 3)
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); // undefined
// ...Przykład z 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
Przekazywanie parametrów do generatora
function* logGenerator() {
console.log(yield);
console.log(yield);
console.log(yield);
}
var gen = logGenerator();
// the first call of next executes from the start of the function
// until the first yield statement
gen.next();
gen.next('pretzel'); // pretzel
gen.next('california'); // california
gen.next('mayonnaise'); // mayonnaise
Wyrażenie return wewnątrz generatora
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 }Generator nie jest typowym konstruktorem
function* f() {}
var obj = new f; // throws "TypeError: f is not a constructor"Specyfikacja
| Specification | Status | Comment |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'function*' in that specification. |
Standard | Initial definition. |
| ECMAScript 2016 (ECMA-262) The definition of 'function*' in that specification. |
Standard | Changed that generators should not have [[Construct]] trap and will throw when used with new. |
| ECMAScript (ECMA-262) The definition of 'function*' in that specification. |
Living Standard |
Kompatybilność przeglądarek
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Edge | Opera | Safari (WebKit) |
|---|---|---|---|---|---|---|
| Basic support | 39.0 | 26.0 (26.0) | No support | 13 | 26 | 10 |
yield* |
(Yes) | 27.0 (27.0) | No support | 13 | 26 | 10 |
IteratorResult object instead of throwing |
(Yes) | 29.0 (29.0) | No support | 13 | (Yes) | ? |
Not constructable with new as per ES2016 |
(Yes) | 43.0 (43.0) | ? | ? | ? | ? |
| Trailing comma in parameters | ? | 52.0 (52.0) | ? | ? | ? |
| Feature | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
|---|---|---|---|---|---|---|---|
| Basic support | No support | (Yes) | 26.0 (26.0) | No support | No support | 10 | 39.0 |
yield* |
No support | (Yes) | 27.0 (27.0) | No support | No support | 10 | (Yes) |
IteratorResult object instead of throwing |
No support | ? | 29.0 (29.0) | No support | No support | ? | (Yes) |
Not constructable with new as per ES2016 |
? | ? | 43.0 (43.0) | ? | ? | ? | ? |
| Trailing comma in parameters | ? | ? | 52.0 (52.0) | ? | ? | ? | ? |
Firefox-specific notes
Generatory i iteratory w Firefox przed wersją 26
Starsze wersje Firefox implementują nieco inną, bardziej archaiczną propozycje specyfikacji. W starszych wersjach definiowanie generatorów odbywało się za pomocą wyłącznie słowa kluczowego function (bez dodatkowej gwiazdki). Tą i wiele innych drobnych różnic można sprawdzić na Legacy generator function.
IteratorResult zwraca obiekt zamiast rzucać wyjątek
Począwszy od silnika Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26), zakończony generator nie rzuca już więcej wyjątkami TypeError "generator has already finished". W zamian za to zwraca obiekt IteratorResult w postaci { value: undefined, done: true } (błąd 958951).
Zobacz także
function* expressionGeneratorFunctionobject- The Iterator protocol
yieldyield*Functionobjectfunction declarationfunction expressionFunctions and function scope- Other web resources:
- 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

