2011年09月28日

JavaScriptでbound method

Function内のthisの値は呼び出し方によって変化するので、下記コードは意図通りに動かない。
//クラス定義
function Hoge() {
    this.propertyA = 1;
}
Hoge.prototype = {
    methodA: function() {
        return this.propertyA;
    }
};

//callback関数を受け取る適当な関数
function fuga(callback) {
    return callback();
}

var hoge = new Hoge();
console.log(fuga(hoge.methodA));    // undefined が出力されてしまう

pythonのbound methodみたいに、インスタンス生成時にthisの値を束縛してくれればインスタンスメソッドの使い勝手がよくなりそうなので、クラス定義を次のように書き換えてみた。
function Hoge() {
    this.propertyA = 1;
    for (var property in this) {
        if (typeof this[property] == 'function') {
            this[property] = (function(context, method) {
                return function() {
                    return method.apply(context, arguments);
                };
            })(this, this[property]);
        }
    }
}
Hoge.prototype = {
    methodA: function() {
        return this.propertyA;
    }
};

var hoge = new Hoge();
console.log(fuga(hoge.methodA));    // ちゃんと 1 が出力される
var a = hoge.methodA;
console.log(a());     // これでも 1 が出力される。

実際のプロダクトではこんなことしないで引数渡すときにjQuery.proxy使うけど。
posted by 膳 at 21:43| Comment(0) | TrackBack(0) | JavaScript