在原型中保留 'this' 上下文

Preserving 'this' context in prototype

这个问题已经有人问过,建议的解决方案是使用 'bind'。但是如何在这种情况下使用 'bind' 呢?

var Fun = function(){
    this.count = 100;
}

Fun.prototype.f = function(){
    console.log("in f : " + this.count);
}

Fun.prototype.g = {
    f : function(){
        console.log("in g-f : " + this.count);
        // Is it possible to use 'bind' here to access 'this' of 'Fun'
    }
}

fun = new Fun();
fun.f(); // Results - in f : 100
fun.g.f(); // Results - in g-f : undefined
fun.g.f.bind(fun)(); // Results - in f : 100

是否可以在 g.f 中使用 bind 以便 fun.g.f() 给出结果 in f : 100

Is it possible to use 'bind' here to access 'this' of 'Fun'

不,因为在您创建第二个 f 时没有 this 可以绑定。您必须在 Fun 中执行此操作:

var Fun = function(){
    this.count = 100;
    this.g = {
        f: function() {
            console.log("in g-f : " + this.count);
        }.bind(this)
    };
};

或不绑定:

var Fun = function(){
    var t = this;
    this.count = 100;
    this.g = {
        f: function() {
            console.log("in g-f : " + t.count);
        }
    };
};

这确实涉及为每个实例创建一个新函数。现代浏览器引擎将在实例之间重用函数的 code,即使创建了不同的函数 objects

如果你想从原型中使用 f 的主体,这也是可能的:如你所示将 g 放在原型上,然后:

var Fun = function(){
    var t = this;
    var oldg = this.g;
    this.count = 100;
    this.g = {
        f: function() {
            return oldg.f.apply(t, arguments);
        }
    };
};

现在,如果 Fun.prototype.g.f 在创建实例后发生变化,您将使用更新后的版本。但是,如果 Fun.prototype.g 被替换为对新对象的引用,它将中断。

不,因为 fun.g 是不同的对象。您所能做的就是在 Fun 的所有实例中放置一个 differnet g 对象,并在其中放置一个绑定函数 f

function Fun() {
  this.count = 100;

  this.g = {
    f: function() {
      console.log("in g-f : " + this.count);
    }.bind(this);
  };
}

Fun.prototype.f = function() {
  console.log("in f : " + this.count);
};