0

エラーのあるこのフィドルがあります --> http://jsfiddle.net/Osoascam/AkZZr/6/ (これはエラーのないバージョンです) --> http://jsfiddle.net/Osoascam/AkZZr/7 /

その中には、モジュール (メイン アプリケーションと同様)、Module.AjaxInterfaceAjax 呼び出し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ですか?どうすれば修正できますか?callまたはを使用できることはわかってapplyいますが、 関数pretendRenderが で呼び出されておりAjaxInterface、 への参照Modules.Inboxが失われています ( を使用しない限りcaller、 では使用できません"strict")。私はそれを保存するために渡すことができることを知っていますthisAjaxInterface、私が本当に望んでいるのは、何が起こっているのかを真に理解し、エレガントなソリューションを作成することです.

4

2 に答える 2

4

this.pretendRender関数への単なる参照/ポインタでありthis、関数が呼び出されたときのコンテキストは多くのことに依存します:

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

thisによって参照される関数がのプロパティとして呼び出されているため、b内部になりますccb


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

thisglobal objectによって参照される関数aが のプロパティとして呼び出されるため、が に設定されます。global object


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

thisによって参照される関数は、オリジナルに設定されたコンテキストで元の関数を呼び出すバインドされた関数であるため、何があっても元のthis内部になります。最新のブラウザには存在しますが、確実に利用できるようにするために含める必要があります。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 に答える