mozilla的绑定函数问题 [英] mozilla's bind function question

查看:93
本文介绍了mozilla的绑定函数问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个关于我在Mozilla网站上找到的bind函数实现的问题。在大多数情况下,这对我来说很有意义,但我无法弄清楚这张支票的用途......

Had a question about a implementation of bind function that I found on Mozilla's site. For the most part it makes sense to me, but I cant figure out what this check is for...

this instanceof nop ? this : ( obj || {} ) 

。显然它检查'this'是否为空函数,但为什么需要绑定空函数。我在firebug中试过它,它有效,但重点是什么?只是想增加我的javascript知识,所以任何帮助将不胜感激。

in the bind function. Obviously its checking if 'this' is the empty function, but why would you need to bind the empty function. I have tried it in firebug, it works, but what is the point? Just trying to increase my javascript knowledge so any help would be appreciated.

if ( !Function.prototype.bind ) {

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

    nop.prototype = self.prototype;

    bound.prototype = new nop();

    return bound;
  };
}


推荐答案

它允许你调用绑定函数作为构造函数而不绑定到原始对象。换句话说,如果用 new 调用它,绑定功能仍然可以像原始的未绑定版本一样工作。

Its allows you to call the bound function as a constructor without being bound to the original object. In other words the "bound" function will still work just like the original, unbound version if you call it with new.

以下是一个例子:

var obj = {};

function foo(x) {
    this.answer = x;
}
var bar = foo.bind(obj);   // "always" use obj for "this"

bar(42);
console.log(obj.answer);   // 42

var other = new bar(1);    // Call bar as a constructor
console.log(obj.answer);   // Still 42
console.log(other.answer); // 1



工作原理



为了简化说明,这里是一个简化版本的代码,只绑定 this ,并且不处理参数或缺少obj参数:

How it works

To simplify the explanation, here's a simplified version of the code that only binds this and doesn't handle arguments or a missing obj parameter:

Function.prototype.bind = function( obj ) {
  var self = this,
  nop = function () {},
  bound = function () {
    return self.apply( this instanceof nop ? this : obj, arguments );
  };

  nop.prototype = self.prototype;
  bound.prototype = new nop();

  return bound;
};

Function.prototype.bind 的行为会有所不同,具体取决于您是将其用作函数还是构造函数(请参阅第15.3.4.5.1节 15.3.4.5.2 。它的主要区别在于它在被称为构造函数时忽略了bound this参数(因为在构造函数中,这个需要是新创建的对象)。所以绑定函数需要一种方法来确定它的调用方式。例如, bound(123) new bound(123)并设置 this 相应的。

The function that gets returned by Function.prototype.bind behaves differently depending on whether you use it as a function, or a constructor (see Section 15.3.4.5.1 and 15.3.4.5.2 of the ECMAScript 5 Language Specification). The primary difference, is that it ignores the "bound this" parameter when it's called as a constructor (since inside a constructor, this needs to be the newly-created object). So the bound function needs a way to determine how it's being called. For example, bound(123) vs. new bound(123) and set this accordingly.

这就是 nop 函数的用武之地。它基本上充当了一个中介class使绑定扩展 nop 扩展 self (调用函数 bind())。这部分设置在这里:

That's where the nop function comes in. It's essentially acting as an intermediate "class" so that bound extends nop which extends self (which is the function bind() was called on). That part is set up here:

nop.prototype = self.prototype;
bound.prototype = new nop();

调用绑定函数时,它返回以下表达式:

When you call the bound function, it returns this expression:

self.apply( this instanceof nop ? this : obj, arguments ) )

此实例nop 通过跟随原型链来确定这个等于 nop.prototype 。通过设置 nop.prototype = self.prototype bound.prototype = new nop(),使用<创建的任何对象code> new bound()将使用 self 中的原始原型通过 bound.prototype 。所以在函数调用中,这个实例nop (即Object.getPrototypeOf(nop)== nop.prototype)是 true 自我使用调用此(新创建的对象)。

this instanceof nop works by following the prototype chain to determine the if any prototype of this is equal to nop.prototype. By setting nop.prototype = self.prototype and bound.prototype = new nop(), any object created with new bound() will be created with the original prototype from self via bound.prototype. So inside the function call, this instanceof nop (i.e. Object.getPrototypeOf(nop) == nop.prototype) is true and self gets called with this (the newly created object).

在正常的函数调用中,'bound()'(没有 new ),此实例nop 将是假的,所以 obj 作为这个上下文传递,这是你在绑定函数上所期望的。

In a normal function call, 'bound()' (without new), this instanceof nop would be false, so obj gets passed as the this context, which is what you would expect on a bound function.

使用中间函数的原因是为了避免调用原始函数(在行 bound.prototype = new nop(); ),可能有副作用。

The reason for using the intermediate function is to avoid calling the original function (in the line bound.prototype = new nop();), which may have side effects.

这篇关于mozilla的绑定函数问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆