0

我有这个有错误的小提琴-> http://jsfiddle.net/Osoascam/AkZZr/6/ (这是没有错误的版本)--> http://jsfiddle.net/Osoascam/AkZZr/7 /

其中有一个模块(如主应用程序),一个Module.AjaxInterface处理 Ajax 调用,一个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";
           }

我的问题是......this参考发生了什么?为什么会变成window? 我该如何解决?我知道我可以使用callor apply,但是pretendRender正在调用该函数AjaxInterface,并且对 的引用Modules.Inbox已经丢失(除非我使用caller,我不能在 下"strict")。我知道我可以通过this保留AjaxInterface它,但我真正想要的是真正了解正在发生的事情并创建一个优雅的解决方案。

4

2 回答 2

4

this.pretendRender只是一个函数的引用/指针,调用函数时的上下文this取决于很多事情:

a.b.c = this.pretendRender;
a.b.c(); 

this将在b里面c,因为被引用的函数c被作为属性调用b


window.a = this.pretendRender;
a(); 

this将被设置为 ,global object因为被引用的函数a被作为global object


a.b.c = this.pretendRender.bind( this );
a.b.c();

this无论如何都将是原始this内部,因为引用的函数是一个绑定函数,它调用原始函数并将上下文设置为 original 。存在于现代浏览器中,但必须包含以确保它可用。ccthis.bind


a.b.c = this.pretendRender;
a.b.c.call( someObject );

this将在someObject里面c,因为它是明确给出的。


由于您使用的是 jQuery,因此this.pretendRender.bind( this );您可以使用successCallback: $.proxy( this.pretendRender, this )

jsfiddle

于 2011-11-16T16:17:18.257 回答
2

this始终是调用函数的对象。它改变。 this.pretendRender不是this在那个时间点附加到对象的方法。它只是一个正在传递的函数。如果您想保证this在该上下文中使用该方法,您需要绑定 this到该函数。像这样的东西(使用闭包):

var me = this;
params = {
    successCallback: function() { return me.pretendRender.apply(me, arguments); },
    ...
}

underscore.js 框架使用_.bind().

于 2011-11-16T16:11:36.520 回答