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

preserve context of variable assigned to an instance method

本文关键字:变量 上下文 实例方法 分配 保留      更新时间:2023-09-26

这一直在躲避我

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 );
}

使用函数#bind:

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

这确保了无论何时调用otherthis指针都将是tmp

由于bind并不是在所有浏览器中都实现的,您可能需要一个类似于上面链接中给出的polyfill。(事实上,我建议你一路走,得到一个ES5垫片。)


如果你愿意放弃原型继承,如果你想在不记得bind的情况下传递方法,这是必要的,那么我建议使用模块模式:

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