检查函数是否为生成器的可靠方法,例如:
let fn = function* () {
yield 100;
}
if (fn instanceof ??) {
for (let value in fn()) {
...
}
}
我能想到的唯一方法是fn.toString().startsWith('function*')
,但这非常黑客且不可靠
context:nodejs 4 +
答案 0 :(得分:11)
Erik Arvidsson makes a good point in this answer这个问题的早期版本(我没想到它是一个傻瓜),因为任何函数都可以返回一个迭代器,这里有一点点检查函数是否是生成器。也就是说,实际上你对信息的处理力度不大,因为非生成器可以返回迭代器。
之前我错了,是比toString
检查更好的方式(如果由于某种原因你根本不需要这样做):
(一次)获取生成器函数的默认constructor
的值,即specified here。它没有像Function
那样的全球性,而且没有。{/ p>
(每当您需要检查时)检查您的目标函数是否为instanceof
生成器函数构造函数。
E.g:
// Once
var GeneratorFunction = (function*(){}).constructor;
// Whenever you need to check
if (fn instanceof GeneratorFunction) {
// Yep, it's a generator function
}
旧事被排除在外:
我在规范中没有看到任何可以让我们直接访问[[FunctionKind]]
内部广告位的内容。
规范does say:
与函数实例不同,作为GeneratorFunction的
prototype
属性值的对象没有constructor
属性,其值为GeneratorFunction实例。
所以理论上:
if (!fn.prototype.hasOwnProperty("constructor")) {
// It's a generator function
}
但是 ,这将是非常不可靠的,因为人们总是这样做(虽然希望人们开始使用class
时不那么喜欢):
function Foo() {
}
Foo.prototype = {
method: function() {}
};
虽然Foo.prototype
对象具有constructor
属性,但它是继承的,而不是"拥有"。我们可以进行in
检查或.constructor == fn
检查,但上述内容仍会误识别。你无法在野外信任constructor
,人们会把它搞得太乱。