保留分配给实例方法的变量的上下文

时间:2011-06-18 05:09:46

标签: javascript

这一直在逃避我。请使用以下代码:

function tSt( val ) {
    this.val = val;
}

tSt.func = function( x ) {
    return x * 2;
}

tSt.prototype.func = function() {
    return tSt.func( this.val );
}

var tmp = new tSt( 5 );

console.log( tmp.func());  // 10

var other = tmp.func;

console.log( other());  // undefined

我希望能够做到这一点的原因是类似以下情况:

(function( funcarr ) {
    for ( var i = 0; i < funcarr.length; i++ )
        console.log( funcarr[i]());
})([ tmp.func ]);

如何实现这一目标?

更新

这是一个可能更全面的解决方案,但我不确定这样做是否有任何缺点:

function tSt( val ) {
    this.val = val;
    this.func = this.func.bind( this );
}

tSt.func = function( x ) {
    return x * 2;
}

tSt.prototype.func = function() {
    return tSt.func( this.val );
}

1 个答案:

答案 0 :(得分:3)

使用Function#bind

var other = tmp.func.bind(tmp);

这可确保无论何时调用otherthis指针都将为tmp

由于bind并未在所有浏览器中实现,因此您可能需要像上面链接中给出的填充。 (事实上​​,我建议你一路走下去,得到一个ES5 shim。)


如果您愿意放弃原型继承,如果您想要传递方法而不记住bind,那么这是必要的,那么我建议module pattern

function TSt(val) {
   // save a reference to our current "this" so that, even inside of methods
   // called from other contexts, we still have it.
   var that = this;

   that.val = val;
   that.func = function () {
       return that.val * 2;
       // Since we're using that instead of this, still works even without bind.
   }
}

var tmp = new TSt(5);
var other = tmp.func;
console.log(other()); // 10

实际上,这种模式的另一个主要好处是你可以获得私有变量:

function Encapsulated(mine, public) {
    var that = this;

    var private = mine * 2;

    that.public = public;
    that.compute = function () {
        return that.public * private;
    };
}

现在Encapsulated个实例的消费者无法访问mineprivate,但只能访问public