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;
}
Combining your solution with other solutions, this avoids the need for the global GeneratorFunction
:
g instanceof (function*() {}).constructor