2011-09-02 168 views
2
Function.prototype.bind = function() { 
    var _this = this, 
     original = _this, 
     args = Array.prototype.slice.call(arguments), 
     _obj = args.shift(), 
     func = function() { 
      var _that = _obj; 
      return original.apply(_that, args.concat(
      Array.prototype.slice.call(
      arguments, args.length))); 
     }; 
    func.bind = function() { 
     var args = Array.prototype.slice.call(arguments); 
     return Function.prototype.bind.apply(_this, args); 
    } 
    return func; 
}; 

我知道这是一个绑定函数。但我不明白它在做什么,特别是args.concat部分。 concat做什么?另外,.bind方法做什么.apply.call不能?这段代码做了什么?

+0

'bind'返回一个函数,'call'和'apply'调用一个函数,它们是不同的动物。当你想要确保稍后使用的函数被特定的上下文调用时使用'bind',同时也可以选择将参数绑定到函数。 –

回答

3

bind函数采用函数并确保它是总是绑定到特定的this值。最简单的例子是事件处理程序。默认情况下,事件处理程序的this值绑定到window。但是,让我们说,你想用一个对象的方法作为听众,并在监听改变一些属性:

var thing = { 
    answer : 4, 
    listener : function() { 
     this.answer = 42; 
    } 
} 
window.onload = thing.listener; 

在onload事件,而不是thing.answer正在改变像预期,window.answer现在是42.所以,我们使用bind

window.onload = thing.listener.bind(thing); 

所以,bind返回一个函数,调用时,调用原始的功能,但与指定this值。

[].concat简单地增加的参数的阵列 - 所以[].concat(5, 4)返回[5, 4],并[5, 4].concat([42])返回[5, 4, 42]。在这种情况下,它用于连接参数 - 您可以将参数传递给bind函数,该函数在函数被调用时将作为参数传递。连接起作用,所以当你调用绑定函数时,你传递的参数也被传递。

2

它似乎是shimFunction.bind()

但我不明白它在做什么,特别是args.concat部分。 concat是做什么的?

Array.concat()连接两个或更多个Array S(以及其它值到Array)。

而且,什么.bind方法做到这一点.apply.call不能?

它返回一个函数的引用,this绑定到任何你想要的。

var newFn = fn.bind(['a', 'b', 'c']); 

// This will call `fn()` with the above `Array` as `this`. 
newFn('first arg', 'second arg'); 

它适用于例如咖喱,返回一个已经设置参数的函数(因为在bind()中设置了this以外,可以设置默认参数)。

+0

奇怪的(或不同的)部分是它为被返回的函数添加一个'.bind'属性'func.bind = function(){...'这样如果你调用'.bind()''反对一个'.bind()'的* result *函数,原型''。bind()'被遮蔽,并且它总是只绑定到原始函数。这是与标准'.bind()'的偏差。 – user113716

+0

...它也非常奇怪地重复其变量2,引用同一个项目的不同名称。它放弃传递给与原始绑定参数位于相同索引的绑定函数调用的参数。非常奇怪的功能。 – user113716

+0

@patrick我确实注意到了重复。奇怪。 – alex