Start · Sprachen · JavaScript · Referenz · function*

function*

Anweisung

Deklariert eine <code>Generator</code>-Funktion, die bei jedem <code>yield</code>-Ausdruck pausiert und einen Iterator zurückgibt.

seit JavaScript ES2015 (ES6) Kategorie: syntax

Signatur

function* name(param1, param2, …) { … }

Beschreibung

Eine Generatorfunktion ist eine besondere Art von Funktion, die ihren Ausführungskontext zwischen mehreren Aufrufen einfriert und schrittweise Werte produziert. Sie wird mit dem Schlüsselwort function* (gesprochen: „function star") deklariert. Beim Aufruf führt sie den Funktionskörper nicht sofort aus, sondern gibt stattdessen ein Generator-Objekt zurück, das das Iterator- sowie das Iterable-Protokoll implementiert.

Innerhalb des Funktionskörpers steuert der yield-Ausdruck den Ablauf: Jedes Mal, wenn .next() auf dem Generator aufgerufen wird, läuft die Ausführung bis zum nächsten yield und pausiert dort. Der an yield übergebene Wert wird als value-Eigenschaft des Iteratorergebnisses zurückgegeben. Mit yield* kann die Ausführung an ein anderes Iterable delegiert werden.

  • Lazy Evaluation: Werte werden erst bei Bedarf berechnet – ideal für potenziell unendliche Sequenzen.
  • Bidirektionale Kommunikation: .next(wert) kann einen Wert in den Generator hineinsenden, der dann als Ergebnis des pausierten yield-Ausdrucks verfügbar ist.
  • Fehlerbehandlung: Mit .throw(fehler) kann eine Ausnahme in den Generator geworfen und mit try/catch im Inneren abgefangen werden. Mit .return(wert) wird der Generator vorzeitig beendet.

Generatorfunktionen eignen sich besonders für benutzerdefinierte Iteratoren, asynchrone Ablaufsteuerung (vor async/await), unendliche Datenströme sowie für das Implementieren des [Symbol.iterator]-Protokolls in eigenen Klassen.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Der Name der Generatorfunktion. Wie bei normalen Funktionen ist der Name in der Deklarationsform erforderlich; bei Ausdrucksformen (const g = function* () {…}) kann er weggelassen werden.
$param1, param2, … any Beliebig viele formale Parameter, genau wie bei einer regulären Funktion. Rest-Parameter (...rest) und Standardwerte (param = default) sind erlaubt.

Rückgabewert

Typ
Generator
Beschreibung
Ein Generator-Objekt, das gleichzeitig Iterator und Iterable ist. Es besitzt die Methoden .next(value), .return(value) und .throw(error).

Beispiele

Einfache Zahlensequenz

function* zahlenBis(max) {
  for (let i = 1; i <= max; i++) {
    yield i;
  }
}

const gen = zahlenBis(3);
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

// Auch per for-of nutzbar
for (const n of zahlenBis(5)) {
  process.stdout.write(n + ' ');
}
// Ausgabe: 1 2 3 4 5
{ value: 1, done: false } { value: 2, done: false } { value: 3, done: false } { value: undefined, done: true } 1 2 3 4 5

Unendlicher Fibonacci-Generator

function* fibonacci() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();
const erste8 = Array.from({ length: 8 }, () => fib.next().value);
console.log(erste8);
[0, 1, 1, 2, 3, 5, 8, 13]

Bidirektionale Kommunikation mit .next(wert)

function* akkumulator() {
  let summe = 0;
  while (true) {
    const eingabe = yield summe;
    if (eingabe === null) break;
    summe += eingabe;
  }
  return summe;
}

const acc = akkumulator();
acc.next();       // Generator starten (erster yield)
console.log(acc.next(10).value); // 10
console.log(acc.next(25).value); // 35
console.log(acc.next(5).value);  // 40
console.log(acc.return());       // { value: 40, done: true }
10 35 40 { value: 40, done: true }

yield* zur Delegation an ein anderes Iterable

function* buchstaben() {
  yield* 'ABC';
}

function* kombiniert() {
  yield 0;
  yield* buchstaben();
  yield 1;
}

console.log([...kombiniert()]);
[0, 'A', 'B', 'C', 1]

// Wichtig · Fallstricke

Kein new: Generatorfunktionen können nicht mit new aufgerufen werden – das wirft einen TypeError.

Kein return als yield: Ein return wert-Statement innerhalb einer Generatorfunktion beendet den Generator und liefert { value: wert, done: true }. Dieser Wert wird von for-of und dem Spread-Operator ignoriert.

Pfeilfunktionen: Generatorfunktionen können nicht als Pfeilfunktion geschrieben werden (() => {} kennt kein *).

Async Generatoren: Ab ES2018 ist async function* verfügbar, das asynchrone Iteratoren erzeugt und mit for await...of konsumiert wird.

Browser-Kompatibilität: function* wird von allen modernen Browsern und Node.js ab Version 4 unterstützt (Baseline: alle modernen Browser).