Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to identify an ES6 generator

Say I've got a generator function like this:

var g = function*() {
  yield 1;
  yield 2;
  yield 3;
};

var gen = g();

How can I tell programmatically that g is a generator function, or that gen is an iterator?

This seems like one possibility:

g.constructor.name === 'GeneratorFunction'

Is there a better way?

Update: I ended up taking an approach similar to Eric's answer, but using eval to first determine whether generators are supported on the target platform in the first place. Here is the implementation:

var GeneratorConstructor = (function() {
  try {
    var generator;
    return eval('generator = function*() { yield 1; };').constructor;

  } catch (e) {
    // If the above throws a SyntaxError, that means generators aren't
    // supported on the current platform, which means isGenerator should
    // always return false. So we'll return an anonymous function here, so
    // that instanceof checks will always return false.
    return function() {};
  }
}());

/**
 * Checks whether a function is an ES6 Harmony generator.
 *
 * @private
 * @param {Function} fn
 * @returns {boolean}
 */
function isGenerator(fn) {
  return fn instanceof GeneratorConstructor;
}
like image 824
Dan Tao Avatar asked Feb 04 '14 17:02

Dan Tao


People also ask

What are ES6 generators?

ES6 Generators are special functions that can be used to control the iteration behavior of a loop. Generators are defined using a function* declaration.

Which is the correct way to declare a generator function?

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

What keyword does a generator use to send a generated value to the caller?

When called, generator functions do not initially execute their code. Instead, they return a special type of iterator, called a Generator. When a value is consumed by calling the generator's next method, the Generator function executes until it encounters the yield keyword.


1 Answers

Combining your solution with other solutions, this avoids the need for the global GeneratorFunction:

g instanceof (function*() {}).constructor
like image 75
Eric Avatar answered Sep 19 '22 08:09

Eric