12

我试图让一个 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 时知道“this”将非常方便。

这似乎很简单,并且可能有一个简单的答案。我正在研究 .apply() 但我不确定它是否有帮助。这篇关于堆栈溢出的帖子有点帮助,但在我将它放入 .done() 函数的那一刻,它就坏了。

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

4

2 回答 2

15

jQueryproxy将返回一个绑定到特定上下文的函数:

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));
};

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

于 2012-09-06T01:40:11.983 回答
2

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。

于 2012-09-06T03:06:58.217 回答