任何人都可以解释上下文在Javascript中使用call
和apply
方法吗?
为什么要使用call
和apply
而不是直接调用函数?
答案 0 :(得分:74)
如果要将不同的this
值传递给该函数,可以使用call
或apply
。从本质上讲,这意味着您要执行一个函数,就好像它是特定对象的方法一样。两者之间的唯一区别是call
期望参数用逗号分隔,而apply
期望数组中的参数。
来自Mozilla's apply
page的示例,其中构造函数是链接的:
function Product(name, price) {
this.name = name;
this.price = price;
if (price < 0)
throw RangeError('Cannot create product "' + name + '" with a negative price');
return this;
}
function Food(name, price) {
Product.apply(this, arguments);
this.category = 'food';
}
Food.prototype = new Product();
function Toy(name, price) {
Product.apply(this, arguments);
this.category = 'toy';
}
Toy.prototype = new Product();
var cheese = new Food('feta', 5);
var fun = new Toy('robot', 40);
Product.apply(this, arguments)
的作用如下:Product
构造函数作为函数应用于每个Food
和Toy
构造函数中,并且每个对象实例都是被传递为this
。因此,Food
和Toy
中的每一个现在都具有this.name
和this.category
属性。
答案 1 :(得分:21)
仅当您使用call
或apply
时,您才能修改函数内的this
上下文。
与其他语言不同 - 在JavaScript中this
不引用当前对象 - 而是引用执行上下文,并且可以由调用者设置。
如果使用new
关键字this
调用函数将正确引用新对象(在构造函数内)..
但在所有其他情况下 - this
将引用全局对象,除非通过调用
答案 2 :(得分:7)
如果要使函数以不同的.call()
值执行,请使用this
。它按指定设置this
值,将参数设置为指定,然后调用该函数。 .call()
与执行函数之间的差异是函数执行时this
指针的值。当你正常执行函数时,javascript决定this
指针将是什么(通常是全局上下文window
,除非函数被调用为对象上的方法)。当您使用.call()
时,您可以准确指定要将this
设置为的内容。
当要传递给函数的参数在数组中时,使用.apply()
。 .apply()
还可以使函数以特定的this
值执行。当您拥有来自其他来源的不确定数量的参数时,最常使用.apply()
。通常使用通过使用特殊局部变量arguments
将参数从一个函数调用传递给另一个函数调用,该变量包含传递给当前函数的参数数组。
答案 3 :(得分:3)
如果您有使用jQuery的经验,您将知道大多数函数都使用this
对象。例如,collection.each(function() { ... });
在此函数内,"this"
引用迭代器对象。这是一种可能的用法。
我个人使用.apply()
来实现请求队列 - 我将一个参数数组推入队列中,当执行它时,我接受一个元素,并将其作为参数传递给使用.apply()
的处理函数,因此如果必须将参数数组作为第一个参数传递,则使代码更清晰。那是另一个例子。
一般情况下,请记住,存在调用函数的方法,有一天您可能会发现它们可以方便地用于实现您的程序。
答案 4 :(得分:0)
我无法想到将thisArg设置为不同的正常情况是使用apply的目的。
apply的目的是将一个值数组传递给希望这些值作为参数的函数。
传播运营商在日常使用中已被取代。
e.g。
// Finding the largest number in an array
`Math.max.apply(null, arr)` becomes `Math.max(...arr)`
// Inserting the values of one array at the start of another
Array.prototype.unshift.apply(arr1, arr2);
// which becomes
arr1 = [...arr2, ...arr1]
答案 5 :(得分:0)
如果您有使用function foo () {
this.helloworld = "hello from foo"
}
foo.prototype.print = function () {
console.log(this.helloworld)
}
foo.prototype.main = function () {
this.print()
}
function bar() {
this.helloworld = 'hello from bar'
}
// declaring print function to override the previous print
bar.prototype.print = function () {
console.log(this.helloworld)
}
var iamfoo = new foo()
iamfoo.main() // prints: hello from foo
iamfoo.main.call(new bar()) // override print and prints: hello from bar
的经验,那么如果将它与继承进行比较并调用父类的属性或方法/函数,则调用和应用将有意义。这与javascript中的调用类似如下:
load