function*

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.

Die function*-Deklaration erstellt eine Bindung einer neuen Generatorfunktion zu einem gegebenen Namen. Eine Generatorfunktion kann beendet und später wieder betreten werden, wobei ihr Kontext (variablen Bindings) über erneute Aufrufe hinweg gespeichert wird.

Sie können auch Generatorfunktionen mithilfe des function* Ausdrucks definieren.

Probieren Sie es aus

function* generator(i) {
  yield i;
  yield i + 10;
}

const gen = generator(10);

console.log(gen.next().value);
// Expected output: 10

console.log(gen.next().value);
// Expected output: 20

Syntax

js
function* name(param0) {
  statements
}
function* name(param0, param1) {
  statements
}
function* name(param0, param1, /* …, */ paramN) {
  statements
}

Hinweis: Generatorfunktionen haben keine Entsprechungen in Pfeilfunktionen.

Hinweis: function und * sind separate Tokens, daher können sie durch Leerzeichen oder Zeilenbegrenzer getrennt werden.

Parameter

name

Der Funktionsname.

param Optional

Der Name eines formalen Parameters für die Funktion. Für die Syntax der Parameter siehe die Funktionen-Referenz.

statements Optional

Die Anweisungen, die den Körper der Funktion bilden.

Beschreibung

Eine function*-Deklaration erstellt ein GeneratorFunction-Objekt. Jedes Mal, wenn eine Generatorfunktion aufgerufen wird, gibt sie ein neues Generator-Objekt zurück, das dem Iterator-Protokoll entspricht. Wenn die next()-Methode des Iterators aufgerufen wird, wird der Körper der Generatorfunktion ausgeführt, bis der erste yield-Ausdruck erreicht wird, der den zurückzugebenden Wert des Iterators angibt oder, mit yield*, an eine andere Generatorfunktion delegiert. Die next()-Methode gibt ein Objekt mit einer value-Eigenschaft zurück, die den erzeugten Wert enthält, und einer done-Eigenschaft, die als Boolean angibt, ob der Generator seinen letzten Wert erzeugt hat. Das Aufrufen der next()-Methode mit einem Argument wird die Ausführung der Generatorfunktion fortsetzen und den yield-Ausdruck, an dem die Ausführung pausierte, mit dem Argument von next() ersetzen.

Generatoren in JavaScript — insbesondere in Kombination mit Promises — sind ein sehr leistungsfähiges Werkzeug für asynchrones Programmieren, da sie die Probleme mit Rückrufen erheblich abmildern — wenn nicht gar vollständig eliminieren —, wie z. B. Callback Hell und Inversion of Control. Eine noch einfachere Lösung für diese Probleme kann jedoch mit async Funktionen erreicht werden.

Eine return-Anweisung in einem Generator führt dazu, dass der Generator beendet wird (d.h. die done-Eigenschaft des von ihm zurückgegebenen Objekts wird auf true gesetzt). Wenn ein Wert zurückgegeben wird, wird dieser als die value-Eigenschaft des vom Generator zurückgegebenen Objekts gesetzt. Ähnlich wie eine return-Anweisung führt ein innerhalb des Generators ausgelöster Fehler dazu, dass der Generator beendet wird — es sei denn, der Fehler wird innerhalb des Generator-Körpers abgefangen. Wenn ein Generator beendet ist, werden nachfolgende next()-Aufrufe keinen Code dieses Generators ausführen, sondern lediglich ein Objekt dieser Form zurückgeben: {value: undefined, done: true}.

function*-Deklarationen verhalten sich ähnlich wie function-Deklarationen — sie werden gehoben an den Anfang ihres Gültigkeitsbereichs und können überall in ihrem Gültigkeitsbereich aufgerufen werden, und sie können nur in bestimmten Kontexten erneut deklariert werden.

Beispiele

Einfaches Beispiel

js
function* idMaker() {
  let index = 0;
  while (true) {
    yield index++;
  }
}

const 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*

js
function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
}

function* generator(i) {
  yield i;
  yield* anotherGenerator(i);
  yield i + 10;
}

const 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

Übergabe von Argumenten an Generatoren

js
function* logGenerator() {
  console.log(0);
  console.log(1, yield);
  console.log(2, yield);
  console.log(3, yield);
}

const 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

Rückgabeanweisung in einem Generator

js
function* yieldAndReturn() {
  yield "Y";
  return "R";
  yield "unreachable";
}

const 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 als Objekteigenschaft

js
const someObj = {
  *generator() {
    yield "a";
    yield "b";
  },
};

const gen = someObj.generator();

console.log(gen.next()); // { value: 'a', done: false }
console.log(gen.next()); // { value: 'b', done: false }
console.log(gen.next()); // { value: undefined, done: true }

Generator als Objektmethode

js
class Foo {
  *generator() {
    yield 1;
    yield 2;
    yield 3;
  }
}

const f = new Foo();
const gen = f.generator();

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 }

Generator als berechnete Eigenschaft

js
class Foo {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
  }
}

const SomeObj = {
  *[Symbol.iterator]() {
    yield "a";
    yield "b";
  },
};

console.log(Array.from(new Foo())); // [ 1, 2 ]
console.log(Array.from(SomeObj)); // [ 'a', 'b' ]

Generatoren sind nicht instanziierbar

js
function* f() {}
const obj = new f(); // throws "TypeError: f is not a constructor

Generator-Beispiel

js
function* powers(n) {
  // Endless loop to generate
  for (let current = n; ; current *= n) {
    yield current;
  }
}

for (const power of powers(2)) {
  // Controlling generator
  if (power > 32) {
    break;
  }
  console.log(power);
  // 2
  // 4
  // 8
  // 16
  // 32
}

Spezifikationen

Specification
ECMAScript® 2026 Language Specification
# sec-generator-function-definitions

Browser-Kompatibilität

Siehe auch