我的 fiddle 有一个错误 --> http://jsfiddle.net/Osoascam/AkZZr/6/ (这是没有错误的版本) --> http://jsfiddle.net/Osoascam/AkZZr/7/
其中有一个模块(如主应用程序)、一个处理 Ajax 调用的 Module.AjaxInterface
、一个 Module.Modules.Inbox
(执行与电子邮件收件箱相关的任务),以及处理多个模块以显示页面的 Module.Pages.Gmail
。所有这些都是使用模块模式完成的。
现在,您可以看到有很多回调。我想知道这些调用中 this
会发生什么情况...
我不明白的是 this
引用发生了什么以及如何保留它:
getMessages: function(params) {
var parameters = params || {};
params = {
// Please note I'm using this, which equals the module
successCallback: this.pretendRender,
successCallbackParameters: parameters,
json: params.json
};
var test = new Module.AjaxInterface(params);
test.ajaxCall();
},
因此,对模块本身内部函数的调用有效...然后,它调用 test.ajaxCalls
,后者又调用 pretendRender()
。现在,在 pretendRende
r 上我有这个:
pretendRender: function(data, parameters) {
// LINE 106 that is causing the ERROR
// It says "this.addColor() is not defined and THIS = window now
data.color = this.addColor();
parameters.successCallback(data);
},
addColor: function() {
return "#AD9";
}
我的问题是...这个
引用发生了什么?为什么会变成window
?我该如何修复它?我知道我可以使用 call
或 apply
,但是在 AjaxInterface
上调用函数 pretendRender
,并且引用Modules.Inbox
已丢失(除非我使用caller
,在“strict”
下我不能使用)。我知道我可以将 this
传递给 AjaxInterface
来保留它,但我真正想要的是真正了解正在发生的事情并创建一个优雅的解决方案。
最佳答案
this.pretendRender
只是一个函数的引用/指针,调用函数时 this
的上下文取决于很多因素:
a.b.c = this.pretendRender;
a.b.c();
this
将是 c
内的 b
,因为 c
引用的函数被作为属性调用b
window.a = this.pretendRender;
a();
this
将被设置为 全局对象
,因为 a
引用的函数正在作为 global 的属性进行调用对象
a.b.c = this.pretendRender.bind( this );
a.b.c();
无论如何,this
都将是 c
内的原始 this
,因为 c
引用的函数是调用原始函数的绑定(bind)函数,上下文设置为原始 this
。 .bind
存在于现代浏览器中,但是 must be included to be sure它可用。
a.b.c = this.pretendRender;
a.b.c.call( someObject );
this
将是 c
内的 someObject
,因为它是明确给出的。
由于您使用的是 jQuery,因此您可以使用 successCallback: $.proxy( this.pretendRender, this ) 而不是
this.pretendRender.bind( this );
关于javascript - 避免丢失此引用以及发生这种情况的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8154690/