javascript - 避免丢失此引用以及发生这种情况的原因

标签 javascript callback this module-pattern

我的 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()。现在,在 pretendRender 上我有这个:

 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?我该如何修复它?我知道我可以使用 callapply,但是在 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 );

jsfiddle

关于javascript - 避免丢失此引用以及发生这种情况的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8154690/

相关文章:

javascript - 在 JavaScript 中使用 InstanceOf 和原型(prototype)继承

swift - 这叫什么回调?

javascript - 向 div 添加事件监听器,该事件监听器可以引用创建该 div 的对象

javascript - 使用 Node js将mysql结果解析为变量

c++ - 将回调函数移动到类会导致错误!

java - 不知道为什么我无法让 addMouseListener(this())、addMouseMotionListener(this()) 工作

javascript - 为什么我不能使用 $(this) jQuery 选择器

javascript - js 正则表达式不匹配单词边界\b

javascript - html jquery 数据属性

javascript - 自定义rc-time-picker的样式