使用Function.pr原型.apply()和Function.pr原型.call()调用函数有什么区别?
var func = function() {
alert('hello!');
};
函数.apply();vs func.call();
上述两种方法之间是否存在性能差异?何时最好使用呼叫转移应用,反之亦然?
使用Function.pr原型.apply()和Function.pr原型.call()调用函数有什么区别?
var func = function() {
alert('hello!');
};
函数.apply();vs func.call();
上述两种方法之间是否存在性能差异?何时最好使用呼叫转移应用,反之亦然?
当前回答
call()方法调用具有给定this值和第二个参数(用逗号分隔的参数)的函数。
object.someMethod.call( someObject, arguments )
apply()方法与调用相同,只是它使用的第二个参数是一个参数数组。
object.someMethod.apply( someObject, arrayOfarguments )
var汽车={name:“雷诺”,国家:“法国”,showBuyer:函数(firstName,lastName){console.log(`${firstName}${lastName}刚刚从${this.country}购买了${this.name});}}const firstName=“Bryan”;const lastName=“Smith”;car.showBuyer(firstName,lastName);//布莱恩刚从法国买了一辆雷诺constobj={name:“玛莎拉蒂”,国家:“意大利”};car.showBuyer.call(obj,firstName,lastName);//布莱恩·史密斯刚从意大利买了一辆玛莎拉蒂car.showBuyer.apply(obj,[firstName,lastName]);//布莱恩·史密斯刚从意大利买了一辆玛莎拉蒂
其他回答
区别在于apply允许您以数组的形式调用带有参数的函数;调用要求显式列出参数。一个有用的助记符是“A代表数组,C代表逗号。”
请参阅MDN的申请和通话文档。
伪语法:
函数.应用(值For This,arrayOfArgs)
函数调用(此值,arg1,arg2,…)
从ES6开始,还可以扩展数组以与调用函数一起使用,您可以在这里看到兼容性。
示例代码:
函数函数(名称、专业){console.log(“我的名字是”+name+“,我是”+profession+“。”);}函数(“John”,“fireman”);函数.应用(未定义,[“Susan”,“学校老师”]);函数调用(未定义,“克劳德”,“数学家”);函数调用(未定义,…[“Matthew”,“物理学家”]);//与排列运算符一起使用
K.Scott Allen对这件事有很好的评论。
基本上,它们在处理函数参数的方式上有所不同。
apply()方法与call()方法相同,只是apply(需要一个数组作为第二个参数。数组表示目标方法的参数。"
So:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
我想展示一个示例,其中使用了“valueForThis”参数:
Array.prototype.push = function(element) {
/*
Native code*, that uses 'this'
this.put(element);
*/
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[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*
这些to方法之间的区别在于,如何传递参数。
“A代表数组,C代表逗号”是一个方便的助记符。
尽管call和apply实现了相同的功能,但我认为至少有一个地方不能使用call,只能使用apply。这是您希望支持继承并希望调用构造函数的时候。
这里有一个函数允许您创建类,它也支持通过扩展其他类来创建类。
function makeClass( properties ) {
var ctor = properties['constructor'] || function(){}
var Super = properties['extends'];
var Class = function () {
// Here 'call' cannot work, only 'apply' can!!!
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];
});
return Class;
}
//Usage
var Car = makeClass({
constructor: function(name){
this.name=name;
},
yourName: function() {
return this.name;
}
});
//We have a Car class now
var carInstance=new Car('Fiat');
carInstance.youName();// ReturnsFiat
var SuperCar = makeClass({
constructor: function(ignore,power){
this.power=power;
},
extends:Car,
yourPower: function() {
return this.power;
}
});
//We have a SuperCar class now, which is subclass of Car
var superCar=new SuperCar('BMW xy',2.6);
superCar.yourName();//Returns BMW xy
superCar.yourPower();// Returns 2.6