JavaScriptでcallback処理で呼元のthisを参照したい時がよくあります。
例えば、下のような感じです。
var Hoge = function(name){ this.name = name; }; Hoge.prototype.method = function(){ var url = ''; var param = {}; $.post(url, param, function(data){ alert(this.name); }); }; var hoge = new Hoge('aaa'); hoge.method();
で、thisの中身はHogeではないので、postのundefinedがalertに表示されます。
これを解決するには、以下のようにbindメソッドを使うとOKです。
Hoge.prototype.method = function(){ var url = ''; var param = {}; $.post(url, param, function(data){ alert(this.name); }.bind(this)); };
だがしかし!!bindはECMAScript5で追加されたので、IE8では動かないのです。
それを解決するには、jQueryの$.proxyを使うと楽にいけます。
Hoge.prototype.method = function(){ var url = ''; var param = {}; $.post(url, param, $.proxy(function(data){ alert(this.name); }, this)); };
じゃぁ、JQueryが使えない時どうするのか??というか、proxyの中身ってどうなってるのか?
ソースをみるとapplyを使っていました。
傍らにあるパーフェクトJavaScriptの185ページを読むと、bindとapplyの違いは以下のようになっていました。
- bindはその場で実行せずにクロージャを返却
- apply(call)はその場で実行
ということで、proxyの中身はapplyを実行する関数を返してあげればOKなのかなと。
function proxy(fn, context){ var proxy = function(){ return fn.apply(context, arguments); }; return proxy; } var Hoge = function(name){ this.name = name; }; Hoge.prototype.method = function(){ var url = ''; var param = {}; $.post(url, param, proxy(function(data){ alert(this.name); }, this)); }; var hoge = new Hoge('aaa'); hoge.method();
これですっきり寝れるや。