Whats a reliable way to check if a function is a generator, e.g.:
let fn = function* () {
yield 100;
}
if (fn instanceof ??) {
for (let value in fn()) {
...
}
}
The only way I can think of is fn.toString().startsWith('function*')
but that's extremely hacky and unreliable
context: nodejs 4+
Erik Arvidsson makes a good point in this answer to an earlier version of this question (it didn't occur to me that it's a dupe), that since any function can return an iterator, there's little point in checking whether a function is a generator or not. That is, there's not much you can do with the information in practical terms, since non-generators can return iterators.
I was wrong before, there is a better way than your toString
check (if for some reason you have a valid need to do it at all):
(Once) Get the value of the default constructor
of a generator function, which is specified here. It doesn't have a global like Function
and such do.
(Whenever you need to check) Check to see if your target function is instanceof
that generator function constructor.
E.g.:
// Once
var GeneratorFunction = (function*(){}).constructor;
// Whenever you need to check
if (fn instanceof GeneratorFunction) {
// Yep, it's a generator function
}
Old things ruled out:
I don't see anything in the specification that lets us directly access the [[FunctionKind]]
internal slot.
The spec does say:
Unlike function instances, the object that is the value of the a GeneratorFunction’s
prototype
property does not have aconstructor
property whose value is the GeneratorFunction instance.
So in theory:
if (!fn.prototype.hasOwnProperty("constructor")) {
// It's a generator function
}
but, that would be incredibly unreliable, as people do things like this all the time (although hopefully less so as people start using class
):
function Foo() {
}
Foo.prototype = {
method: function() {}
};
While that Foo.prototype
object has a constructor
property, it's inherited, not "own". We could do an in
check, or a .constructor == fn
check, but the above would still mis-identify it. You just can't trust constructor
in the wild, people mess it up too much.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With