5

MDN 为那些没有原生绑定方法的浏览器指定了一个 polyfill 绑定方法:https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

此代码具有以下行:

aArgs.concat(Array.prototype.slice.call(arguments))

它作为 args 传递给函数的 apply 方法:

fToBind.apply(this instanceof fNOP && oThis
                             ? this
                             : oThis,
                           aArgs.concat(Array.prototype.slice.call(arguments)));

但是,这一行实际上重复了参数,因此如果我将绑定方法称为:

fnX.bind({value: 666}, 1, 2, 3)

传递给 fnX 的参数是:

[1, 2, 3, Object, 1, 2, 3] 

运行以下示例并查看控制台输出http://jsfiddle.net/dtbkq/

但是 fnX 报告的参数是 [1, 2, 3] 是正确的。有人可以解释为什么在传递给应用调用时参数重复但没有出现在函数参数变量中吗?

4

3 回答 3

4

那里有两种不同的arguments情况。每次调用一个函数时,除其他外,一个arguments对象被设置为所有传递的参数(如果arguments被访问)。

首先提到的arguments是 的参数bind(),它们将成为初始参数。

第二次提到的是在绑定代理函数上调用的下一组参数。因为argumentsname 会影响其父级arguments(以及this需要分离的上下文),所以它们存储在 name 下aArgs

这允许部分函数应用(有时称为currying)。

var numberBases = parseInt.bind(null, "110");

console.log(numberBases(10));
console.log(numberBases(8));
console.log(numberBases(2));

js小提琴

于 2012-10-22T00:11:38.963 回答
1

如果您改为检查aArgs.concat(Array.prototype.slice.call(arguments))from inside 的值,fBound您会看到您的期望。关键是参数是指在已经绑定的函数上调用的附加参数。

于 2012-10-22T00:13:36.860 回答
1

不,当您从 登录时xx() arguments:[1, 2, 3]

bind2console.log(aArgs.concat(Array.prototype.slice.call(arguments)));,在哪里aArgs = Array.prototype.slice.call(arguments, 1)。那么还有什么比[1, 2, 3, {value: 666}, 1, 2, 3]你期望的?那些不是arguments传递给 fnX 的,而是那些传递给 bind:[{value: 666}, 1, 2, 3]的。

在绑定函数内部,aArgs变量仍然包含[1, 2, 3],而argumentsnow 是空的——你确实调用了x().

于 2012-10-22T00:13:05.297 回答