有人可以在JavaScript中解释这个功能

时间:2015-06-08 15:13:14

标签: javascript arrays

我正在通过在线TUT了解javaScript中的callapply。此函数允许传递更多参数,而不是具有固定数量。

var calculate = function(){
        var fn = Array.prototype.pop.apply(arguments);
        return fn.apply(null, arguments);
    };

我无法解决这个问题。

var fn = Array.prototype.pop.apply(arguments);

TUT的主持人,解释如下:

我们将apply方法绑定到arguments对象上。这将给我们Function Object并将其分配给fn变量。它还会从Function Object对象中删除arguments。因为数组的pop method接受数组中的最后一个元素,所以它会从数组中删除它,然后分配给所谓的方法。在这种情况下,fn变量。

令我困惑的是以下内容:

  

我们将apply方法绑定到arguments对象上。这是   打算给我们Function Object

     

它还会移除Function Object中的arguments   对象

当我们在return语句中写道时:

 return fn.apply(null, arguments);

为什么我们要包括null

3 个答案:

答案 0 :(得分:2)

Array.prototype.pop.apply(arguments);

当你有一个函数时,会自动生成一个arguments个对象,这是一个类似于数组的参数对象。如果你称这个假函数:

someFunction('hello', 'world');

someFunction看起来像这样:

function someFunction() {
    console.log(arguments);
}

console.log将输出['hello', 'world']。但是,不要混淆......这不是Array对象!它是一个“类似阵列”的对象。因此,您不能说arguments.pop() ...因为arguments没有该方法(它属于Array.prototype)。但是,正常Array个对象执行可以访问Array.prototype(例如[1,2,3].pop() // => [1,2])。

当你说.apply()时,第一个参数是上下文......它设置this。实际上,Array.prototype.pop.apply(arguments)是一种模仿arguments.pop()的聪明方式。但是你不能arguments.pop(),因为它没有pop方法。

return fn.apply(null, arguments);中,null是第一个参数,因为我们不需要为此示例设置新的上下文。 arguments是第二个参数,因为它被传入以与fn一起使用。

.apply()返回一个函数对象,因此返回如下内容:

function() { ... }

然后我们可以调用该函数。

顺便说一下,.pop()会改变原始对象(在这种情况下,类似于数组的对象arguments)。因此,您将arguments传递给fn,但它缺少之前的最后一项。

答案 1 :(得分:1)

传递给calculate的最后一个参数被假定为一个函数。它从arguments列表中弹出。 (使用apply因为arguments不是真正的数组。)

使用fn列表的其余部分调用此弹出函数(arguments)。 (所有其他参数传递给calculate)。 arguments列表不再包含fn,因为pop()会修改原始对象。

使用

NULL是因为调用fn时没有 this 的值。 (见MDN

如果您拨打calculate,例如

calculate(2, 3, function(a, b){ return a + b });

它将返回5.

答案 2 :(得分:1)

根据MDN

  

语法

     

fun.apply(thisArg,[argsArray])

     

参数

     

thisArg:   这个值为乐趣召唤提供了。请注意,这可能不是方法看到的实际值:如果方法是非严格模式代码中的函数, null和undefined将替换为全局对象,原始值将是装箱。

     

argsArray:   一个类数组的对象,指定应该调用fun的参数,如果不应该为函数提供参数,则为null或undefined。从ECMAScript 5开始,这些参数可以是类似通用数组的对象而不是数组。有关浏览器兼容性信息,请参阅下文。