function*
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.
Thefunction*
declaration creates abinding of a new generator function to a given name. A generator function can be exited and later re-entered, with its context (variablebindings) saved across re-entrances.
You can also define generator functions using thefunction*
expression.
Try it
function* generator(i) { yield i; yield i + 10;}const gen = generator(10);console.log(gen.next().value);// Expected output: 10console.log(gen.next().value);// Expected output: 20
Syntax
function* name(param0) { statements}function* name(param0, param1) { statements}function* name(param0, param1, /* …, */ paramN) { statements}
Note:Generator functions do not have arrow function counterparts.
Note:function
and*
are separate tokens, so they can be separated bywhitespace or line terminators.
Parameters
name
The function name.
param
OptionalThe name of a formal parameter for the function. For the parameters' syntax, see theFunctions reference.
statements
OptionalThe statements comprising the body of the function.
Description
Afunction*
declaration creates aGeneratorFunction
object. Each time a generator function is called, it returns a newGenerator
object, which conforms to theiterator protocol. When the iterator'snext()
method is called, the generator function's body is executed until the firstyield
expression, which specifies the value to bereturned from the iterator or, withyield*
, delegatesto another generator function. Thenext()
method returns an object with avalue
property containing the yielded value and adone
property which indicates whether the generator has yielded its last value, as a boolean.Calling thenext()
method with an argument will resume the generatorfunction execution, replacing theyield
expression where an execution waspaused with the argument fromnext()
.
Generators in JavaScript — especially when combined with Promises — are a verypowerful tool for asynchronous programming as they mitigate — if not entirely eliminate — the problems with callbacks, such asCallback Hell andInversion of Control.However, an even simpler solution to these problems can be achievedwithasync functions.
Areturn
statement in a generator, when executed, will make the generatorfinish (i.e., thedone
property of the object returned by it will be set totrue
). If a value is returned, it will be set as thevalue
property of the object returned by the generator.Much like areturn
statement, an error thrown inside the generator willmake the generator finished — unless caught within the generator's body.When a generator is finished, subsequentnext()
calls will not execute anyof that generator's code, they will just return an object of this form:{value: undefined, done: true}
.
function*
declarations behave similar tofunction
declarations — they arehoisted to the top of their scope and can be called anywhere in their scope, and they can be redeclared only in certain contexts.
Examples
Basic example
function* idMaker() { let index = 0; while (true) { yield index++; }}const gen = idMaker();console.log(gen.next().value); // 0console.log(gen.next().value); // 1console.log(gen.next().value); // 2console.log(gen.next().value); // 3// …
Example with yield*
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); // 10console.log(gen.next().value); // 11console.log(gen.next().value); // 12console.log(gen.next().value); // 13console.log(gen.next().value); // 20
Passing arguments into Generators
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 statementgen.next(); // 0gen.next("pretzel"); // 1 pretzelgen.next("california"); // 2 californiagen.next("mayonnaise"); // 3 mayonnaise
Return statement in a generator
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 as an object property
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 as an object method
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 as a computed property
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' ]
Generators are not constructable
function* f() {}const obj = new f(); // throws "TypeError: f is not a constructor
Generator example
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}
Specifications
Specification |
---|
ECMAScript® 2026 Language Specification # sec-generator-function-definitions |
Browser compatibility
See also
- Functions guide
- Iterators and generators guide
- Functions
GeneratorFunction
function*
expressionfunction
async function
async function*
- Iteration protocols
yield
yield*
Generator
- Regenerator on GitHub
- Promises and Generators: control flow utopia presentation by Forbes Lindesay at JSConf (2013)
- Task.js on GitHub
- You Don't Know JS: Async & Performance, Ch.4: Generators by Kyle Simpson