使用'instanceof function(){}'的原因是什么?

时间:2011-06-16 17:30:09

标签: javascript function bind instanceof prototype-programming

在Mozilla开发人员中心,有一个关于Function.prototype.bind功能的页面,并为不支持此功能的浏览器提供兼容性功能。

但是,在分析此兼容性代码时,我无法找出他们使用instanceof nop的原因。 nop已设置为function() {}。这与bind的ECMA规范的哪一部分相符?什么变量是function() {}的实例?

以下内容返回false,因此我不完全知道它的用途。在进行instanceof function() {}检查时会发生什么事情?

(function() {}) instanceof (function() {}) // false

代码如下:

Function.prototype.bind = function( obj ) {
    if(typeof this !== 'function')
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');

    var slice = [].slice,
        args = slice.call(arguments, 1), 
        self = this, 
        nop = function () {}, 
        bound = function () {
          return self.apply( this instanceof nop ? this : ( obj || {} ), 
                              args.concat( slice.call(arguments) ) );    
        };

    bound.prototype = this.prototype;

    return bound;
};

2 个答案:

答案 0 :(得分:8)

有人编辑了使其有用的部分。以下是它过去的样子:

Function.prototype.bind = function( obj ) {
    var slice = [].slice,
    args = slice.call(arguments, 1), 
    self = this, 
    nop = function () {}, 
    bound = function () {
        return self.apply( this instanceof nop ? this : ( obj || {} ), 
                            args.concat( slice.call(arguments) ) );    
    };

    // These lines are the important part
    nop.prototype = self.prototype;
    bound.prototype = new nop();

    return bound;
};

我在这里回答了另一个问题(但代码是正确的):mozilla's bind function question

this instanceof nop检查的原因是,如果将绑定函数作为构造函数调用(即使用new运算符),则this绑定到新对象而不是无论你传递给bind

为了解释“重要部分”,nop基本上被插入到原型链中,以便当您将该函数作为构造函数调用时,this 是一个实例nop

因此,如果您运行var bound = original.bind(someObject);,原型链将如下所示:

  original
     |
    nop
     |
   bound

我猜他们使用nop而不是this instanceof self的原因是为了使绑定函数拥有自己的prototype属性(继承自self)。有可能它不应该是为什么它被部分编辑出来的原因。无论如何,现在的代码是不正确的,但只要您不将该函数用作构造函数,它就会起作用。

答案 1 :(得分:3)

该实现似乎有错误。永远不会使用nop(实例化任何东西)对instanceof检查的期望,对于任何事情都不可能是真的,因为没有对象可以从nop实例化,而// Identical definition, but different Function instances var nop = function () {}, mop = function () {}; var obj1 = new mop; obj1 instanceof mop // true obj1 instanceof nop // false 深埋在该闭包中

考虑一下:

{{1}}