我在 Nodejs v0.11.2 中使用了生成器,我想知道如何检查我的函数的参数是生成器函数。
我找到了这种方式,typeof f === 'function' && Object.getPrototypeOf(f) !== Object.getPrototypeOf(Function)
但我不确定这是否是好的(并在未来工作)方式。
您对这个问题有什么看法?
我在 Nodejs v0.11.2 中使用了生成器,我想知道如何检查我的函数的参数是生成器函数。
我找到了这种方式,typeof f === 'function' && Object.getPrototypeOf(f) !== Object.getPrototypeOf(Function)
但我不确定这是否是好的(并在未来工作)方式。
您对这个问题有什么看法?
在最新版本的 nodejs(我用 v0.11.12 验证过)中,您可以检查构造函数名称是否等于GeneratorFunction
. 我不知道这是什么版本,但它有效。
function isGenerator(fn) {
return fn.constructor.name === 'GeneratorFunction';
}
我们在 TC39 面对面会议中讨论过这个问题,并且故意不公开检测函数是否为生成器的方法。原因是任何函数都可以返回一个可迭代对象,所以它是函数还是生成器函数都没有关系。
var iterator = Symbol.iterator;
function notAGenerator() {
var count = 0;
return {
[iterator]: function() {
return this;
},
next: function() {
return {value: count++, done: false};
}
}
}
function* aGenerator() {
var count = 0;
while (true) {
yield count++;
}
}
这两个行为相同(减去 .throw() 但也可以添加)
这适用于节点和火狐:
var GeneratorFunction = (function*(){yield undefined;}).constructor;
function* test() {
yield 1;
yield 2;
}
console.log(test instanceof GeneratorFunction); // true
但是如果你绑定一个生成器,它就不起作用,例如:
foo = test.bind(bar);
console.log(foo instanceof GeneratorFunction); // false
我正在使用这个:
var sampleGenerator = function*() {};
function isGenerator(arg) {
return arg.constructor === sampleGenerator.constructor;
}
exports.isGenerator = isGenerator;
function isGeneratorIterator(arg) {
return arg.constructor === sampleGenerator.prototype.constructor;
}
exports.isGeneratorIterator = isGeneratorIterator;
TJ Holowaychuk 的co
库具有检查某事物是否是生成器函数的最佳功能。这是源代码:
function isGeneratorFunction(obj) {
var constructor = obj.constructor;
if (!constructor) return false;
if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true;
return isGenerator(constructor.prototype);
}
参考:https : //github.com/tj/co/blob/717b043371ba057cb7a4a2a4e47120d598116ed7/index.js#L221