如果函数是调用了.bind(),是否无法判断函数是否为生成函数?

时间:2014-11-06 00:11:23

标签: javascript node.js generator ecmascript-harmony

看起来在任何生成器函数上调用.bind(this)会破坏我查看函数是否为生成器的能力。关于如何解决这个问题的任何想法?

var isGenerator = function(fn) {
    if(!fn) {
        return false;
    }

    var isGenerator = false;

    // Faster method first
    // Calling .bind(this) causes fn.constructor.name to be 'Function'
    if(fn.constructor.name === 'GeneratorFunction') {
        isGenerator = true;
    }
    // Slower method second
    // Calling .bind(this) causes this test to fail
    else if(/^function\s*\*/.test(fn.toString())) {
        isGenerator = true;
    }

    return isGenerator;
}

var myGenerator = function*() {
}

var myBoundGenerator = myGenerator.bind(this);

isGenerator(myBoundGenerator); // false, should be true

3 个答案:

答案 0 :(得分:6)

由于.bind()会返回一个新的(存根)函数,该函数仅使用.apply()调用原始函数以附加正确的this值,因此它显然不再是您的生成器是你问题的根源。

此节点模块中有一个解决方案:https://www.npmjs.org/package/generator-bind

您可以按原样使用该模块,也可以查看它们是如何解决的(基本上它们会使.bind()返回的新函数也成为生成器。)

答案 1 :(得分:1)

是的,即使调用了.bind(),也可以判断函数是否为生成器:

function testIsGen(f) {
  return Object.getPrototypeOf(f) === Object.getPrototypeOf(function*() {});
}

答案 2 :(得分:0)

这个包有解决方案:

https://www.npmjs.org/package/generator-bind

基本上,为了使它工作,您需要填充Function.prototype.bind或调用自定义bind()方法。