我试图让一个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
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));
};
apply
和 call
可以使用指定的上下文立即执行函数,但是 proxy
和 bind
返回一个可以在以后使用或传递给其他函数的函数。
该 this
JavaScript中的“变量”称为“调用对象”,并在调用其封闭函数时确定(而不是在定义时)。它可以设置几种不同的方式:
- 你可以使用它来设置它
.
运算符(例如 myObject.myFunction()
)
- 您可以使用函数设置它
call()
要么 apply()
方法
- 您可以(在ES5下)使用函数永久绑定它
bind()
方法
- 如果上述方法都没有将其设置为其他方法,则它将默认为全局对象
要理解的重要一点是(除了上面的方法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。