电话和申请有什么区别?

使用callapply之间的区别是什么?调用函数?

varfunc=function(){
alert('hello!');
};

func.apply();vsfunc.call();

两者之间是否存在性能差异上述两种方法?何时最好使用call而不是apply,反之亦然?

转载于:https://stackoverflow的.com/问题/1986896/什么-是最差之间呼叫和-适用?页=1&标签=票

不同之处在于apply允许您使用arguments调用该函数作为阵列;call要求显式列出参数。一个有用的助记符是Aarray和Ccomma。”

请参阅有关申请的MDN文档和致电。

伪语法:

theFunction.apply(valueForThis,arrayOfArgs)

theFunction。call(valueForThis,arg1,arg2,...)

从ES6开始,还有可能spread数组,用于调用函数,您可以在此处查看兼容性。

示例代码:



functiontheFunction(name,profession){
console.log(”我的名字是“+名字+”,我是“+专业+”。“;;
}

TheFunction(”John“,”fireman“);
theFunction.apply(undefined,[”Susan“,”schoolteacher“]);
theFunction.call(未定义,“克劳德”,“数学家”);
theFunction.call(undefined,...[“Matthew”,“物理学家”]);//与扩展运算符一起使用



K.ScottAllen已关于此事的一个很好的写作。

基本上,它们在处理函数参数方面有所不同。

apply()方法与call()相同,但apply()需要一个数组作为第二个参数。数组表示目标方法的参数。“

所以:

//假设你有f
函数f(消息){...}
f.call(接收者,“测试”);
f.apply(接收者,[“测试”]);

要回答有关何时使用每个功能的部分,如果您不知道该号码,请使用apply您将要传递的参数,或者它们是否已经在数组或类似数组的对象中(如arguments对象来转发您自己的参数。否则,请使用call,因为没有必要将参数包装在数组中。

f.call(thisObject,a,b,c);//固定数量的参数

ff。(thisObject,arguments);//转发此函数的参数

varargs=[];
while(...){
\args.push(some_value());
}

nf.apply(thisObject,args);//未知数量的参数

当我没有传递任何参数时(比如你的例子),我更喜欢call因为我调用函数。apply意味着你函数应用于(不存在的)参数。

除非您愿意,否则不应存在任何性能差异使用apply并将参数包装在一个数组中(例如f.apply(thisObject,[a,b,c])而不是f.call(thisObject,a,b,c))。我没有对它进行过测试,因此可能存在差异,但它会特定于浏览器。如果你没有数组中的参数,那么call可能会更快,如果你这样做,apply会更快。

虽然这是一个古老的话题,但我只想指出.call比.apply略快。我无法确切地告诉你原因。

参见jsPerf,http://jsperf.com/test-call-vs-apply/3


[更新]

DouglasCrockford简要提到了两者之间的区别,这可能有助于解释性能差异......http://youtu.be/ya4UHuXNygM?t=15m52s

Apply接受一系列参数,而Call接受零个或多个个体参数!啊哈!

.apply(this,[...])

.call(this,param1,param2,param3,param4...)

我想展示一个例子,其中使用'valueForThis'参数:

Array.prototype.push=function(element){
/*
本机代码*,使用'this'
this.put(element);
*/
}
vararray=[];
array.push(1);
array.push.apply(数组,[2,3]);
Array.prototype.push.apply(数组,[4,5]);
array.push。call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1,2,3,4,5,6,7,8,9]

**详情:http://es5.github.io/#x15.4.4.7*

这是一个很好的助记符。Apply使用Arrays而Always需要一个或两个参数。当你使用C时,你必须C计算参数的数量。

我们可以区分调用和应用方法,如下所示

CALL:带参数的函数单独提供。 如果你知道要传递的参数或者没有传递参数,你可以使用call。

APPLY:调用一个带有作为数组提供的参数的函数。如果您不知道将有多少参数传递给函数,则可以使用apply。

使用applyovercall有一个优点,我们不需要更改参数个数我们只能更改传递的数组。

性能没有太大差别。但我们可以说,与apply相比,调用有点快,因为数组需要在apply方法中进行求值。

这是一篇小帖子,我写到:

http://sizeableidea.com/call-versus-apply-javascript/

varobj1={which:“obj1”},
obj2={which:“obj2”};

functionexecute(arg1,arg2){
console.log(this.which,arg1,arg2);
}

//使用call
execute.call(obj1,“dan”,“stanhope”);
//输出:obj1danstanhope

//使用apply
execute.apply(obj2,[“dan”,“stanhope”]);
//输出:obj2danstanhope

//使用旧学校
execute(“dan”,“stanhope”);
//output:undefined“dan”“stanhope”

Call()采用逗号分隔的参数,例如:

.call(scope,arg1,arg2,arg3)

和apply()接受一个参数数组,例如:

。apply(scope,[arg1,arg2,arg3])

这里有几个用法示例: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/

有时一个对象借用另一个对象的函数很有用,这意味着借用对象只是简单地执行lent函数,就像这是它自己的。

一个小代码示例:

varfriend={
car:false,
lendCar:function(canLend){
this.car=canLend;
}

};


我={

汽车:false,
gotCar:function(){
返回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()接受参数列表,而apply()接受单个参数数组

即使callapply达成同样的效果,我认为还有至少一个你不能使用call的地方,但只能使用apply。那是你想要支持继承并想要调用构造函数的时候。

这个函数允许你创建类,它们也支持通过扩展其他类来创建类。

functionmakeClass(properties){
varctor=properties['constructor']||function(){}
varSuper=properties['extends'];
varClass=function(){
//这里'call'不起作用,只有'apply'可以!!!
if(Super))
Super.apply(this,arguments);
ctor.apply(this,arguments);
}
if(Super){
Class.prototype=Object.create(Super.prototype);
Class.prototype.constructor=Class;
}
Object.keys(properties).forEach(function(prop){
if(prop!=='constructor'&&prop!=='extends')
Class.prototype[prop]=properties[prop];
});
返回Class;
}

//用法
varCar=makeClass({
构造函数:函数(名称){
this.name=name;
},
yourName:function(){
返回此.name;
}
});
//我们现在有一个Car类
varcarInstance=newCar('Fiat');
nInInstance.youName();//ReturnsFiat

varSuperCar=makeClass({
constructor:function(ignore,power){
this.power=power;
},
extends:Car,
yourPower:function(){
returnthis.power;
}
});
//我们现在有一个SuperCar类,它是Car
var的子类superCar=newSuperCar('BMWxy',2.6);

superCar.yourName();//返回BMWxy
superCar.yourPower();//返回2.6

使用Call,Apply和Bind的另一个例子。 Call和Apply之间的区别很明显,但Bind是这样的:

  1. Bind返回可以执行的函数的实例
  2. 第一个参数是'this'
  3. 第二个参数是逗号分隔参数列表(如调用

}

functionPerson(name){
this.name=name;
}

Person.prototype.getName=function(a,b){
returnthis.name+“”+a+“”+b;
}

varreader=newPerson('JohnSmith');

reader.getName=function(){
//Apply和Call执行函数并返回值

//也注意提取'getName'原型的不同方法
varbaseName=Object.getPrototypeOf(this).getName.apply(this,[“isa”,“boy”]);
console.log(“Apply:”+baseName);

varbaseName=Object.getPrototypeOf(reader).getName.call(this,“isa”,“boy”);
console.log(“Call:”+baseName);

//绑定返回可以调用的函数
varbaseName=Person.prototype.getName.bind(this,“isa”,“boy”);
console.log(“Bind:”+baseName());
}

reader.getName();
/*输出
应用:JohnSmith是个男孩
呼叫:JohnSmith是男孩
Bind:JohnSmith是个男孩
*/

这些方法之间的区别在于,您希望如何传递参数。

“Aforarray和Cforcomma“是一个方便的助记符。

调用和应用两者用于在执行函数时强制this值。唯一的区别是call需要n+1参数,其中1是this'n'argumentsapply只接受两个参数,一个是this,另一个是参数数组。

我在applyovercall是我们可以轻松地将函数调用委托给其他函数;

functionsayHello(){
console.log(this,arguments);
}

函数hello(){
sayHello.apply(this,arguments);
}

varobj={name:'myname'}
hello。call(obj,'some','arguments');

观察我们如何轻松地将hello委托给sayHello代码>使用apply,但是使用call,这很难实现。

区别在于call()分别获取函数参数,apply()获取数组中的函数参数。

主要区别在于,使用call,我们可以正常更改范围并传递参数,但apply允许您使用参数调用它一个数组(将它们作为数组传递)。但就你在代码中的作用而言,它们非常相似。

虽然这个函数的语法几乎与 apply()的语法相同,最根本的区别是call()接受一个参数 list,而apply()接受一个参数数组。

如你所见,那里并不是一个很大的区别,但仍有一些情况我们更喜欢使用call()或apply()。例如,查看下面的代码,它使用apply方法从MDN中查找数组中的最小和最大数字:

//数组中的最小/最大数字
varnumbers=[5,6,2,3,7];

//使用Math.min/Math.maxapply
varmax=Math.max.apply(null,numbers);
//这大约等于Math.max(数字[0],...)
//或Math.max(5,6,...)

varmin=Math.min.apply(null,数字)

所以主要区别在于我们传递参数的方式:

调用:

function.call(thisArg,arg1,arg2,...);

应用

function.apply(thisArg,[argsArray]);