Reason behind using 'instanceof function() {}'?

血红的双手。 提交于 2020-01-01 04:11:05

问题


On Mozilla Developer Center, there is a page about the Function.prototype.bind function and provides a compatibility function for browsers which do not support this function.

However, when analyzing this compatibility code I cannot find out why they use instanceof nop. nop has been set to function() {}. What part of the ECMA specification on bind does this correspond with? And what variables are an instance of function() {}?

The following returns false, so I don't completely know what it is used for. What things return true when doing an instanceof function() {} check?

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

The code is as follows:

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;
};

回答1:


Someone edited out the part that makes it useful. Here's what it used to look like:

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;
};

I answered another question that was asking the same thing (but when the code was correct) here: mozilla's bind function question.

The reason for the this instanceof nop check is so that if you call the bound function as a constructor (i.e. with the new operator), this is bound to the new object instead of whatever you passed to bind.

To explain the "important part", nop is basically getting inserted into the prototype chain so that when you call the function as a constructor, this is an instance of nop.

So if you run var bound = original.bind(someObject); the prototype chain will look like this:

  original
     |
    nop
     |
   bound

My guess for why they used nop instead of this instanceof self is so that the bound function would have it's own prototype property (that inherits from self's). It's possible that it's not supposed to which could be why it got partially edited out. Regardless, the code as it is now is not correct, but will work as long as you don't use the function as a constructor.




回答2:


There seems to be an error with that implementation. nop is never used (to instantiate anything) expect for that instanceof check, which can never be true for anything since no object can be instantiated from nop, which is buried deep in that closure.

Consider this:

// Identical definition, but different Function instances
var nop = function () {},
    mop = function () {};

var obj1 = new mop;

obj1 instanceof mop // true
obj1 instanceof nop // false


来源:https://stackoverflow.com/questions/6376062/reason-behind-using-instanceof-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!