直接调用函数和在闭包中使用call() apply()的区别是什么?

3

我在《权威指南》中看到了这段代码:

function not(f)
{
  return function()
  {
    var result=f.apply(this,arguments);
    return !result;
  }
}

我理解不了的是,由于函数 f 已经在闭包中,它的 this 已经是当前的 this,为什么这段代码片段不直接使用 var result=f(arguments);

我甚至读过一些使用 undefined/null 作为第一个参数的 call,我认为这些完全可以被直接调用替代:

...
while(i>len)
{
  if(i in a)
     accumulator=f.call(undefined,accumulator,a[i],i,a);
  i++;
}
...

作者为什么使用call()而不是直接调用?直接调用函数和带有undefined作为第一个参数的call()之间有什么区别吗?

1个回答

4
var result=f(arguments);

将调用f()并传递单个参数,即arguments对象。

var result=f.apply(this,arguments);

...将逐个(这么说)通过arguments对象传递参数调用f()

所以,假设f()被定义为:

function f(a,b,c) {
    // do something with a, b, c
    return c;
}

当给出三个参数1,2,3时,使用arguments的直接调用如下:

f([1,2,3]);

请注意,arguments 是类似数组的对象;它不是一个真正的数组。

.apply() 版本则是这样的:

f(1,2,3);

@nnnnnn 谢谢!讲得非常清楚!不过第二段代码中带有 undefined 作为第一个参数的 call() 是什么意思? - dotslashlu
2
在这种情况下,如果代码不是在严格模式下运行,undefined 将被全局对象替换(但仅适用于调用本地函数对象的情况,对于内置方法或主机方法可能不起作用)。请参见 ECMA §15.3.4.4§13.2.1 - RobG
是的,就像RobG所说的那样。如果没有上下文,我无法确定这对你展示的.call()代码片段有什么好处。(似乎与在其他代码片段中使用.apply()的原因完全无关。) - nnnnnn
有人能给出速度比较和何时使用哪种情况的用例吗? - pokemon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接