JS: Generator Function
New in JS2015.
What is Generator Function
A generator function is a function that returns a Generator .
Syntax
function * name (params) {body}
-
generator function declaration.
function * (params) {body}
-
generator function expression
{etc, * name (params) {body}, etc}
-
Generator Method, defined inside Object Literal Expression
The space before or after the asterisk * can be omitted.
- In the generator function body, you use
yield
instead ofreturn
. - Each yield is a stopping point.
- When the generator function is called, it exit at yield point and save state.
- When it is its called again, it resume at the yield point.
💡 TIP: Arrow Function cannot be used for generator function.
Example
// define a generator function function* gf() { yield 3; yield 4; yield 5; } // generator function returns a generator object const gg = gf(); // now gg is a generator // test. // generator is also a iterable object, we can use Array.from to turn it into array console.log(Array.from(gg)); // [ 3, 4, 5 ]
Purpose of Generator Function
Basically the only purpose of generator function is to create Generator .
The Type of Generator Function
Type of Generator Function is a Generator Function object, and typeof
operator returns "function"
.
Type of Generator is Generator object (and not a function object), and typeof
operator returns "object"
.
// define a generator function function* ff() { yield 3; yield 4; yield 5; } // type of Generator Function is function console.log(typeof ff === "function"); const gg = ff(); // type of Generator is object console.log(typeof gg === "object");
〔see Determine Type of Object〕
Generator Function Constructor
Another way to create generator function is by calling the generator function constructor.
In JavaScript spec, generator function constructor is written as “GeneratorFunction”. But it is not a keyword you can use.
There's no syntax that represents generator function constructor “GeneratorFunction” , but you can get it by:
const GeneratorFunction = Reflect.getPrototypeOf(function* () {}).constructor;
Once you have the constructor GeneratorFunction, you can create new generator function by the syntax:
GeneratorFunction (p1, p2, … , pn, body)
where all arguments are strings.
It works similarly to Function Constructor.
〔see Function Constructor〕
For example,
const gf = Reflect.getPrototypeOf ( function *(){} ).constructor ;
const ff = gf ( " yield 3; yield 4; yield 5;" );
is roughly equivalent to:
function * ff () { yield 3; yield 4; yield 5; }
Here is a full example.
const gf = Reflect.getPrototypeOf(function* () {}).constructor; // define a generator function const ff = gf(" yield 3; yield 4; yield 5;"); // this is basically equivalent to // function * ff () { yield 3; yield 4; yield 5; } // generator function returns a generator object const gg = ff(); // now gg is a generator object // because generator is also a iterable object // we can use for-of loop on iterable object for (let p of gg) { console.log(p); } // prints // 3 // 4 // 5
- In general, there is no practical use of Generator Function constructor.
- Use the syntax
function * name () {body}
- instead.
- The reason the generator function constructor object exist is so that JavaScript can maintain some language structure consistency.
- That is, each object X has a constructor object C that creates instances of X, and the constructor object C has property
"prototype"
that is the parent object of instances of X, etc.