JQuery递延变更”;这个“;

JQuery deferred changes "this"

本文关键字:这个 JQuery      更新时间:2023-09-26

我正试图让一个javascript对象运行一个延迟方法,当它执行.done()时,调用同一对象中的一个函数。我遇到了问题,因为"this"变成了延迟对象,而不是调用它的对象

PageObject.prototype.successFunction = function() {
  console.log(arguments);
  return console.log(this.name + " Success function called");
};
PageObject.prototype.loadPage = function(url) {
  return $.when($.mobile.loadPage("pages/" + url))
    .done(this.successFunction);
};
var pg = new PageObject();
pg.loadPage("test.html");

如何将"this"发送到successFunction?这个PageObject也会被其他人扩展,所以在运行successFunction时知道"这个"将非常方便。

这看起来很简单,而且可能有一个简单的答案。我在研究.apply(),但我不确定它是否有帮助。这篇关于堆栈溢出的文章有点帮助,但当我把它放入.done()函数时,它就崩溃了。

函数作为参数(带参数)--JavaScript

jQuery的proxy将返回一个绑定到特定上下文的函数:
PageObject.prototype.loadPage = function(url) {
  return $.when($.mobile.loadPage("pages/" + url))
    .done($.proxy(this.successFunction, this));
};

还有ES5的bind,其操作类似,但需要在旧浏览器中填充

PageObject.prototype.loadPage = function(url) {
  return $.when($.mobile.loadPage("pages/" + url))
    .done(this.successFunction.bind(this));
};

applycall可以使用指定的上下文立即执行函数,但proxybind返回一个可以稍后使用或传递给其他函数的函数。

JavaScript中的this"变量"被称为"调用对象",并在调用其封闭函数时(而不是在定义它时)确定。它可以通过几种不同的方式设置:

  1. 您可以使用.运算符(例如myObject.myFunction())进行设置
  2. 可以使用函数的call()apply()方法进行设置
  3. 您可以(在ES5下)使用函数的bind()方法永久绑定它
  4. 如果上面的任何方法都没有将其设置为其他对象,则它将默认为全局对象

需要理解的重要一点是(除了上面的方法3),这一切都是关于函数在被调用时如何被调用,而不是如何被引用,也不是如何存储,也不是在哪里创建。

在您的案例中,您将this.successFunction作为jQuery调用的函数引用传递,但它并没有以这种方式调用它(因为它只是得到了对该函数的引用,而没有得到任何关于该函数应该如何调用的信息)。

jQuery的$.proxy()或ES5的.bind()方法可以使用一些奇特的技巧,但归根结底,最简单的处理方法是通过闭包范围的变量保留this,并使用函数包装器:

PageObject.prototype.loadPage = function(url) {
    var self = this;
    return $.when($.mobile.loadPage("pages/" + url))
            .done(function () { self.successFunction(); });
};

请注意,我们使用方法1将successFunction的调用对象显式绑定为与loadPage的调用对象相同。它简短、简单、清晰,在ES3下运行良好,不依赖于jQuery。