如何检查一个variables是否是一个生成器函数? (例如函数*收益率)
什么是一个可靠的方法来检查一个函数是否是一个生成器,例如:
let fn = function* () { yield 100; } if (fn instanceof ??) { for (let value in fn()) { ... } }
我能想到的唯一方法是fn.toString().startsWith('function*')
但这是非常hacky和不可靠
上下文:nodejs 4+
Erik Arvidsson在这个问题的一个早期版本(我没有想到这是一个愚蠢的) 中回答了这个问题,因为任何函数都可以返回一个迭代器,所以在检查一个函数是否是一个生成器或不。 也就是说,你可以用实际的术语来处理这些信息,因为非生成器可以返回迭代器。
我以前是错的,有比你的toString
检查更好的方法(如果由于某种原因,你有一个有效的需要做的):
-
(一次)获取此处指定的生成器函数的默认
constructor
函数的值。 它没有一个全球性的Function
,这样做。 -
(每当你需要检查)检查你的目标函数是否是该生成器函数构造函数的
instanceof
。
例如:
// Once var GeneratorFunction = (function*(){}).constructor; // Whenever you need to check if (fn instanceof GeneratorFunction) { // Yep, it's a generator function }
旧事物排除:
在规范中我没有看到任何让我们直接访问[[FunctionKind]]
内部插槽的内容。
规范确实说 :
与函数实例不同,作为GeneratorFunction的
prototype
属性值的对象不具有其值为GeneratorFunction实例的constructor
属性。
所以在理论上:
if (!fn.prototype.hasOwnProperty("constructor")) { // It's a generator function }
但是 ,这将是非常不可靠的,因为人们总是这样做(尽pipe人们开始使用class
希望不大):
function Foo() { } Foo.prototype = { method: function() {} };
虽然Foo.prototype
对象具有constructor
属性,但它是inheritance的,而不是“自己的”。 我们可以做一个检查,或一个.constructor == fn
检查,但上述仍然会错误识别它。 你不能相信野外的constructor
,人们把它搞得太多了。