在 Javascript 中使用调用和应用的上下文?

IT技术 javascript
2021-02-22 12:08:50

任何人都可以解释在 Javascript 中使用的上下文callapply方法吗?

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

6个回答

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

Mozillaapply页面的一个示例,其中构造函数被链接:

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属性。

只是关于提供的代码片段的问题,为什么 Toy's 和 Food 的原型被 Product 对象替换?
2021-04-28 12:08:50
评论只是为了碰撞@davids 问题:我们为什么需要这样做Toy.prototype = new Product();我对此进行了测试,删除这些行似乎对最终结果没有影响。
2021-05-09 12:08:50
@davids & @adrianp :需要让 Food 和 Toy 从 Product 继承。看这个例子:jsfiddle.net/Shawn/xNEYf我删除了Toy.prototype = new Product();但留Food.prototype = new Product();在了里面,所以现在 Food 继承自 Product,但 Toy 没有。我还在Product的prototype中添加了一个方法,从Food and Toy中调用,让继承的缺失更加明显(打开控制台运行代码,Food可以调用从Product继承的方法,但是Toy不能,并且抛出错误) .
2021-05-14 12:08:50
我想我只是不明白这样做的目的,而不是一些看起来容易得多的事情,例如this
2021-05-16 12:08:50
当与对象文字一起使用时,如何使用原型?
2021-05-20 12:08:50

仅当您使用callapply可以修改this函数内部的上下文时。

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

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

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

声明“但在所有其他情况下 - 这将引用全局对象,除非通过调用明确设置”应更正为以下内容:“但在所有其他情况下,除非通过调用明确设置,否则这将引用全局对象,如果使用非严格模式下的 Ecmascript 3 或 Ecmascript 5(或更高版本)。但是,在严格模式下的 Ecmascript 5(或更高版本)中,如果未明确设置,则始终未定义,并且 JS 引擎将在您访问它时抛出异常。” 参考:stackoverflow.com/questions/9822561/...
2021-04-22 12:08:50
如果使用obj.whatever();语法,它可能指的是调用者 obj
2021-04-26 12:08:50

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

您可以使用.apply(),当你想传递给函数的参数是一个数组。 .apply()也可以使函数以特定this执行.apply()当您有不确定数量的来自其他来源的参数时,最常使用。通过使用arguments包含传递给当前函数的参数数组的特殊局部变量它也经常用于将参数从一个函数调用传递到另一个函数调用

我找到了MDN引用页面.CALL()。适用()有帮助。

谢谢,你解释的很好。终于明白第一个参数的用法了。
2021-05-18 12:08:50

如果您有使用 jQuery 的经验,您就会知道大多数函数都使用this对象。例如,collection.each(function() { ... }); 在这个函数内部,"this"指的是迭代器对象。这是一种可能的用法。

我个人曾经用于.apply()实现请求队列 - 我将一个参数数组推入队列,当需要执行它时,我获取一个元素,并将其作为处理函数的参数传递使用.apply(),从而使如果必须将参数数组作为第一个参数传递,则代码更清洁。那是另一个例子。

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

如果您有Object Oriented Programmingthen call 和 apply 的经验,如果您将它与继承进行比较并从子类覆盖父类的属性或方法/函数,那么调用和应用将是有意义的。这与 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