使用“instanceof function() {}”背后的原因?

发布于 2024-11-15 22:34:38 字数 1166 浏览 4 评论 0原文

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

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

下面返回false,所以我不完全知道它的用途。执行 instanceof function() {} 检查时哪些内容会返回 true?

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

生生不灭 2024-11-22 22:34:38

有人编辑掉了有用的部分。这是它以前的样子:

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 的绑定函数问题

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

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

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

  original
     |
    nop
     |
   bound

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

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.

风吹过旳痕迹 2024-11-22 22:34:38

该实现似乎存在错误。 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文