由于bind
不是跨浏览器(旧的)函数,因此有一个polyfill :( 来自John Resig的书)
/*1*/ Function.prototype.bind = function ()
/*2*/ {
/*3*/ var fn = this,
/*4*/ args = Array.prototype.slice.call(arguments),
/*5*/ object = args.shift();
/*6*/ return function ()
/*7*/ {
/*8*/ return fn.apply(object,
/*9*/ args.concat(Array.prototype.slice.call(arguments)));
/*10*/ };
/*11*/ };
但我不明白我们为什么需要arguments
行#9
。
我的意思是:
如果我有这个对象:
var foo = {
x: 3
}
我有这个功能:
var bar = function(p,b){
console.log(this.x+' '+p+' '+b);
}
所以,如果我希望bar
在foo
上下文中运行,带参数 - 我需要做的就是:
var boundFunc = bar.bind(foo,1,2)
boundFunc ()...
因此,当我运行var.bind(foo,1,2)
时,arguments
为[object Object],1,2
。
这些参数保存在第4行。
大
现在,bind
函数返回自己的闭包函数:
function ()
{
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
}
问题
为什么我们需要arguments
?看起来他们似乎是这样的:
var boundFunc = bar.bind(foo,1,2)
boundFunc (more1,more2....) //<----- ??
我错过了什么吗?
Oonce我设置了第一个var boundFunc = bar.bind(foo,1,2)
,我已经声明了参数。为什么我们需要它们两次?
答案 0 :(得分:13)
您可以将两个参数传递给绑定函数:
1)当你调用bind(第一个arguments
)时。这些在调用时始终应用于绑定函数。
2)调用绑定函数时(第二个arguments
)。这些是你提到的“more1,more2”。这些更改取决于调用绑定参数时提供的内容。
第9行将原始绑定参数与提供的额外参数组合在一起。
我猜你可能会混淆的概念是你最初不必绑定所有参数 - 你只能绑定上下文对象,或者你也可以绑定第一个参数但是有绑定函数的调用者供应剩下的。例如:
function sum() {
var _sum = 0
for (var i = 0; i < arguments.length ; i++) {
_sum += arguments[i];
}
return _sum;
}
var sum_plus_two = sum.bind({},2);
sum_plus_two(5,7) == 14;
答案 1 :(得分:4)
.bind
也可用作partial application解决方案。事件处理程序可能是最好的例子:
var handler = function(data, event) { };
element.addEventListener('click', handler.bind(null, someData));
如果不传递来自实际函数调用的参数,则无法访问事件对象。