W3cubDocs

/JavaScript

function*

The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.

You can also define generator functions using the GeneratorFunction constructor, or the function expression syntax.

Syntax

function* name([param[, param[, ... param]]]) {
   statements
}
name
The function name.
param
The name of a formal parameter for the function.
statements
The statements comprising the body of the function.

Description

Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.

Generators in JavaScript -- especially when combined with Promises -- are a very powerful tool for asynchronous programming as they mitigate -- if not entirely eliminate -- the problems with callbacks, such as Callback Hell and Inversion of Control.
This pattern is what async functions are built on top of.

Calling a generator function does not execute its body immediately; an iterator object for the function is returned instead. When the iterator's next() method is called, the generator function's body is executed until the first yield expression, which specifies the value to be returned from the iterator or, with yield*, delegates to another generator function. The next() method returns an object with a value property containing the yielded value and a done property which indicates whether the generator has yielded its last value as a boolean. Calling the next() method with an argument will resume the generator function execution, replacing the yield expression where execution was paused with the argument from next().

A return statement in a generator, when executed, will make the generator finished (i.e the done property of the object returned by it will be set to true). If a value is returned, it will be set as the value property of the object returned by the generator.
Much like a return statement, an error thrown inside the generator will make the generator finished -- unless caught within the generator's body.
When a generator is finished, subsequent next calls will not execute any of that generator's code, they will just return an object of this form: {value: undefined, done: true}.

Examples

Simple example

function* idMaker() {
  var index = 0;
  while (index < index+1)
    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); // 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;
}

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

Passing arguments into Generators

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

var 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

Return statement in a generator

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 }

Generators are not constructable

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

Generator defined in an expression

const foo = function* () {
  yield 10;
  yield 20;
};

const bar = foo();
console.log(bar.next()); // {value: 10, done: false}

Specifications

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.
Draft

Browser compatibilityUpdate compatibility data on GitHub

Desktop
Chrome Edge Firefox Internet Explorer Opera Safari
Basic support 39 13 26 No 26 10
IteratorResult object instead of throwing 49 13 29 No Yes Yes
Not constructable with new (ES2016) Yes ? 43 No Yes 10
Trailing comma in parameters ? ? 52 ? Yes ?
Mobile
Android webview Chrome for Android Edge Mobile Firefox for Android Opera for Android iOS Safari Samsung Internet
Basic support Yes 39 Yes 26 Yes 10 4.0
IteratorResult object instead of throwing Yes Yes Yes 29 Yes Yes Yes
Not constructable with new (ES2016) Yes Yes ? 43 Yes 10 Yes
Trailing comma in parameters ? ? ? 52 ? ? ?
Server
Node.js
Basic support 4.0.0
4.0.0
0.12
Disabled
Disabled From version 0.12: this feature is behind the --harmony runtime flag.
IteratorResult object instead of throwing Yes
Not constructable with new (ES2016) Yes
Trailing comma in parameters 8.0.0

Firefox-specific notes

Generators and iterators in Firefox versions before 26

Older Firefox versions implement an older version of the generators proposal. In the older version, generators were defined using a regular function keyword (without an asterisk) among other differences. See Legacy generator function for further information.

IteratorResult object returned instead of throwing

Starting with Gecko 29 (Firefox 29 / Thunderbird 29 / SeaMonkey 2.26), the completed generator function no longer throws a TypeError "generator has already finished". Instead, it returns an IteratorResult object like { value: undefined, done: true } (bug 958951).

See also

© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*