MDN在调用apply时绑定为什么使用concat参数

时间:2012-10-22 00:05:25

标签: javascript bind apply

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

但是,这一行实际上重复了参数,所以如果我将bind方法调用为:

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

传递给fnX的参数是:

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

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

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

3 个答案:

答案 0 :(得分:4)

arguments在两个不同的背景下。每次调用函数时,都会将arguments对象设置为传递的所有参数(如果访问arguments)。

arguments的第一个提及是bind()的参数,它将成为初始参数。

第二个提到的是绑定代理函数调用的下一组参数。由于arguments名称会影响其父arguments(以及需要分隔的this上下文),因此它们会以名称aArgs存储。

这允许部分功能应用(有时称为 currying )。

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

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

jsFiddle

答案 1 :(得分:1)

没有。当您从x登录时, x() 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] 还有什么呢?这些不是传递给fnX的arguments,而是传递给bind [{value: 666}, 1, 2, 3]的那些。

在绑定函数中,aArgs变量仍包含[1, 2, 3],而arguments现在为空 - 您确实调用了x()

答案 2 :(得分:1)

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