使用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和Apply之间的区别很明显,但Bind的工作原理如下:
Bind返回可以执行的函数的实例第一个参数是“this”第二个参数是逗号分隔的参数列表(如Call)
}
function Person(name) {
this.name = name;
}
Person.prototype.getName = function(a,b) {
return this.name + " " + a + " " + b;
}
var reader = new Person('John Smith');
reader.getName = function() {
// Apply and Call executes the function and returns value
// Also notice the different ways of extracting 'getName' prototype
var baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);
console.log("Apply: " + baseName);
var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy");
console.log("Call: " + baseName);
// Bind returns function which can be invoked
var baseName = Person.prototype.getName.bind(this, "is a", "boy");
console.log("Bind: " + baseName());
}
reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/
其他回答
主要的区别是,使用调用,我们可以改变作用域并按正常方式传递参数,但apply允许您使用参数作为数组调用它(将它们作为数组传递)。但就它们在代码中的作用而言,它们非常相似。
虽然此函数的语法与apply(),基本区别是call()接受一个参数list,而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]);
K.Scott Allen对这件事有很好的评论。
基本上,它们在处理函数参数的方式上有所不同。
apply()方法与call()方法相同,只是apply(需要一个数组作为第二个参数。数组表示目标方法的参数。"
So:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
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]);//布莱恩·史密斯刚从意大利买了一辆玛莎拉蒂
虽然这是一个老话题,但我只是想指出,.call比.apply稍快。我不能告诉你确切的原因。
参见jsPerf,http://jsperf.com/test-call-vs-apply/3
[更新!]
Douglas Crockford简要提到了两者之间的差异,这可能有助于解释性能差异。。。http://youtu.be/ya4UHuXNygM?t=15m52s
Apply接受一个参数数组,而Call接受零个或多个单独的参数!啊哈!
.apply(此,[…])
.调用(this,param1,param2,param3,param4…)
摘要:
call()和apply()都是位于Function.prototype上的方法。因此,它们可以通过原型链在每个函数对象上使用。call()和apply()都可以执行具有指定值this的函数。
call()和apply()之间的主要区别是必须向其中传递参数的方式。在call()与apply(()中,您都将希望作为值的对象作为第一个参数传递为this。其他参数的不同之处如下:
使用call(),您必须正常输入参数(从第二个参数开始)使用apply(),必须传入参数数组。
例子:
让obj={val1:5,值2:10}常量总和=函数(val3,val4){返回this.val1+this.val2+val3+val4;}console.log(summary.apply(obj,[2,3]));//首先,我们在第一个参数中为其赋值//使用apply,我们必须传入一个数组console.log(summary.call(obj,2,3));//通过调用,我们可以单独传入每个参数
为什么我需要使用这些功能?
在javascript中,这个值有时很棘手。该值在执行函数时确定,而不是在定义函数时确定。如果我们的函数依赖于此绑定的权限,我们可以使用call()和apply()来强制执行此行为。例如:
var name='unwantedGlobalName';常量对象={name:“Willem”,sayName(){console.log(this.name);}}let copiedMethod=obj.sayName;//我们将函数存储在copiedmethod变量中copiedMethod();//现在是窗口,unwantedGlobalName将被记录copiedMethod.call(obj);//我们强制这是obj,Willem被记录