使用call
和apply
调用函数有什么区别?
var func = function() {
alert('hello!');
};
func.apply();
与 func.call();
前述两种方法之间是否存在性能差异?什么时候最好使用call
over apply
,反之亦然?
使用call
和apply
调用函数有什么区别?
var func = function() {
alert('hello!');
};
func.apply();
与 func.call();
前述两种方法之间是否存在性能差异?什么时候最好使用call
over apply
,反之亦然?
主要区别在于,使用call时,我们可以像正常情况一样更改范围并传递参数,但是apply允许您使用参数作为Array来调用它(将它们作为数组传递)。但是就它们在代码中要做的事情而言,它们非常相似。
尽管此函数的语法与apply()的语法几乎相同,但基本区别在于call()接受参数列表,而apply()接受单个参数数组。
因此,正如您所看到的,并没有太大的区别,但是在某些情况下,我们更喜欢使用call()或apply()。例如,查看下面的代码,该代码使用apply方法从MDN查找数组中最小和最大的数字:
// min/max number in an array
var numbers = [5, 6, 2, 3, 7];
// using Math.min/Math.max apply
var max = Math.max.apply(null, numbers);
// This about equal to Math.max(numbers[0], ...)
// or Math.max(5, 6, ...)
var min = Math.min.apply(null, numbers)
因此,主要的区别只是传递参数的方式:
调用:
function.call(thisArg, arg1, arg2, ...);
应用:
function.apply(thisArg, [argsArray]);
这是我写的一篇小文章:
http://sizeableidea.com/call-versus-apply-javascript/
var obj1 = { which : "obj1" },
obj2 = { which : "obj2" };
function execute(arg1, arg2){
console.log(this.which, arg1, arg2);
}
//using call
execute.call(obj1, "dan", "stanhope");
//output: obj1 dan stanhope
//using apply
execute.apply(obj2, ["dan", "stanhope"]);
//output: obj2 dan stanhope
//using old school
execute("dan", "stanhope");
//output: undefined "dan" "stanhope"
区别在于,分别call()
采用函数参数,并apply()
采用数组中的函数参数。
这些方法之间的区别在于,您要如何传递参数。
“ A用于数组,C用于逗号”是一个方便的助记符。
我们可以区分调用和应用方法,如下所示
CALL:带有参数的函数单独提供。如果您知道要传递的参数,或者没有要传递的参数,则可以使用call。
APPLY:调用带有以数组形式提供的参数的函数。如果您不知道要传递给函数多少参数,则可以使用apply。
使用apply over调用有一个优势,我们只需要更改传递的数组就不需要更改参数数。
性能没有太大差异。但是我们可以说调用与应用相比要快一些,因为数组需要在apply方法中求值。
基本区别在于,它call()
接受参数列表,而apply()
接受单个参数数组。
有时一个对象借用另一个对象的功能很有用,这意味着借用对象只是像执行其自己的操作一样简单地执行了lent函数。
一个小代码示例:
var friend = {
car: false,
lendCar: function ( canLend ){
this.car = canLend;
}
};
var me = {
car: false,
gotCar: function(){
return this.car === true;
}
};
console.log(me.gotCar()); // false
friend.lendCar.call(me, true);
console.log(me.gotCar()); // true
friend.lendCar.apply(me, [false]);
console.log(me.gotCar()); // false
这些方法对于赋予对象临时功能非常有用。
Call()采用逗号分隔的参数,例如:
.call(scope, arg1, arg2, arg3)
和apply()需要一个参数数组,例如:
.apply(scope, [arg1, arg2, arg3])
以下是一些其他用法示例:http : //blog.i-evaluation.com/2012/08/15/javascript-call-and-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
尽管这是一个老话题,但我只是想指出.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...)
这是一个很好的助记符。 一个人使用A rays,一个人使用一或两个参数。当您使用Ç所有你必须ç指望。2-15参数的个数。
斯科特·艾伦(K. Scott Allen)在这件事上写得很好。
基本上,它们在处理函数参数的方式上有所不同。
apply()方法与call()相同,只是apply()需要一个数组作为第二个参数。该数组代表目标方法的参数。”
所以:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
让我为此添加一些细节。
这两个调用几乎是等效的:
仅有很小的区别:
因此,这些调用相互补充。我们期望的迭代,
call
作品,我们期待一个类似数组的,apply
作品。And for objects that are both iterable and array-like, like a real array, we technically could use any of them, but apply will probably be faster because most JavaScript engines internally optimize it better.