使用Function.prototype.apply()
和Function.prototype.call()
调用函数有什么区别?
var func = function() {
alert('hello!');
};
func.apply();
对比 func.call();
上述两种方法之间是否存在性能差异?什么时候最好使用call
over apply
,反之亦然?
使用Function.prototype.apply()
和Function.prototype.call()
调用函数有什么区别?
var func = function() {
alert('hello!');
};
func.apply();
对比 func.call();
上述两种方法之间是否存在性能差异?什么时候最好使用call
over apply
,反之亦然?
不同之处在于apply
,您可以将函数arguments
作为数组调用;call
需要明确列出参数。有用的助记是“甲用于一个rray和ç为Ç OMMA”。
伪语法:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, ...)
从 ES6 开始,还可以spread
将数组与call
函数一起使用,您可以在此处查看兼容性。
示例代码:
function theFunction(name, profession) {
console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator
K. Scott Allen 有一篇关于此事的好文章。
基本上,它们在处理函数参数的方式上有所不同。
apply() 方法与 call() 相同,除了 apply() 需要一个数组作为第二个参数。该数组表示目标方法的参数。”
所以:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
要回答有关何时使用每个函数的部分,apply
如果您不知道将传递的参数数量,或者它们是否已经在数组或类似数组的对象中(例如arguments
转发您自己的参数的对象),请使用。call
否则使用,因为不需要将参数包装在数组中。
f.call(thisObject, a, b, c); // Fixed number of arguments
f.apply(thisObject, arguments); // Forward this function's arguments
var args = [];
while (...) {
args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments
当我不传递任何参数(如您的示例)时,我更喜欢,call
因为我正在调用该函数。apply
意味着你正在申请的功能的(不存在)的参数。
不应该有任何性能差异,除非您使用apply
并将参数包装在数组中(例如f.apply(thisObject, [a, b, c])
代替f.call(thisObject, a, b, c)
)。我没有测试过它,所以可能会有差异,但它会非常特定于浏览器。call
如果您还没有数组中的参数,这可能会更快,如果您这样做,速度可能会更快apply
。
这是一个很好的助记符。 A ply使用A数组,而A总是使用一两个参数。当您使用Ç所有你必须ç指望。2-15参数的个数。
虽然这是一个老话题,但我只想指出 .call 比 .apply 稍快。我不能确切地告诉你为什么。
参见 jsPerf,http: //jsperf.com/test-call-vs-apply/3
[ UPDATE!
]
Douglas Crockford 简要提到了两者之间的区别,这可能有助于解释性能差异... http://youtu.be/ya4UHuXNygM?t=15m52s
Apply 接受一组参数,而 Call 接受零个或多个单个参数!啊哈!
.apply(this, [...])
.call(this, param1, param2, param3, param4...)