我正在通过在线TUT了解javaScript中的call
和apply
。此函数允许传递更多参数,而不是具有固定数量。
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
?
答案 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开始,这些参数可以是类似通用数组的对象而不是数组。有关浏览器兼容性信息,请参阅下文。