Trwa tłumaczenie tego artykułu.

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 yieldyield 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 Latest Draft (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

Autorzy i etykiety dokumentu

 Autorzy tej strony: AndrzejSala, labs4apps
 Ostatnia aktualizacja: AndrzejSala,