【问题标题】:Is it impossible to tell if a function is a generator function if .bind() has been called on it?如果 .bind() 已被调用,是否无法判断一个函数是否为生成器函数?
【发布时间】:2015-01-02 09:02:12
【问题描述】:

看起来在任何生成器函数上调用 .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

【问题讨论】:

标签: javascript node.js generator ecmascript-harmony


【解决方案1】:

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

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

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

【讨论】:

  • 绑定的生成器仍然是生成器,可以使用 yield* 进行测试。我在下面发布了我的答案。 (说句公道话,有可能从 1.5 年前开始进行了更正)
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    这个包有解决办法:

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

    基本上,为了让它工作,你要么需要 polyfill Function.prototype.bind 要么调用自定义的 bind() 方法。

    【讨论】:

      猜你喜欢
      • 2014-06-22
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      • 2015-07-18
      • 2010-09-10
      • 1970-01-01
      相关资源
      最近更新 更多