在 Javascript 中使用调用和应用?

伙计们,谁能解释一下在 Javascript 中使用 callapply方法的上下文?

为什么使用 callapply而不是直接调用函数?

31590 次浏览

只有在使用 callapply时,才能修改函数内部的 this上下文。

与其他语言不同,JavaScriptthis不引用当前对象,而是引用执行上下文,并且可以由调用者设置。

如果您使用 new关键字 this调用函数,那么它将正确地引用新对象(在构造函数内部)。.

但在所有其他情况下,除非通过调用显式设置,否则 this将引用全局对象

当要向函数传递不同的 this值时,可以使用 callapply。本质上,这意味着您希望将函数作为特定对象的方法来执行。两者之间的唯一区别是,call期望参数以逗号分隔,而 apply期望参数在数组中。

来自 Mozilla 的 apply页面的一个例子,其中构造函数是链式的:

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构造函数作为函数应用于 FoodToy构造函数中,每个对象实例作为 this传递。因此,每个 FoodToy现在都具有 this.namethis.category属性。

如果您有使用 jQuery 的经验,就会知道大多数函数都使用 this对象。例如,collection.each(function() { ... }); 在这个函数中,"this"引用迭代器对象。

我个人使用 .apply()来实现一个请求队列——我将一个参数数组放入队列中,当执行时间到来时,我取一个元素,并使用 .apply()将其作为处理函数的参数传递,因此,如果必须将一个参数数组作为第一个参数传递,那么代码会变得更简洁。这是另一个例子。

一般来说,只要记住这些调用函数的方法是存在的,您可能有一天会发现它们很方便地用于实现您的程序。

当希望使用不同的 this值执行函数时,可以使用 .call()。它设置指定的 this值,设置指定的参数,然后调用函数。.call()和只执行函数的区别在于执行函数时 this指针的值。当您正常执行函数时,javascript 决定 this指针将是什么(通常是全局上下文 window,除非该函数被作为对象上的方法调用)。使用 .call()时,需要精确地指定将 this设置为什么。

当要传递给函数的参数在数组中时,可以使用 .apply().apply()还可以导致使用特定的 this值执行函数。当来自其他来源的参数数量不确定时,最常使用 .apply()。它通常使用特殊的局部变量 arguments将参数从一个函数调用传递给另一个函数调用,arguments包含传递给当前函数的参数数组。

我发现 . call ()。申请()的 MDN 参考页面很有帮助。

我想不出任何正常的情况下,将 this Arg 设置为不同的值是使用 application 的目的。

Application 的目的是将一个值数组传递给一个希望将这些值作为参数的函数。

它已经在所有常规的日常使用中被传播操作员所取代。

例如:。

// 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]

如果您有使用 Object Oriented Programming的经验,那么调用和应用将是有意义的,如果您将其与继承进行比较,并重写子类中父类的属性或方法/函数。与 javascript 中的调用类似如下:

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