3

在以下情况下,我感到困惑:

function foo() {
}

foo.prototype.bar1 = function() {
  console.log(this); // shows "Window"!!
}

foo.prototype.bar2 = function(func) {
  func();
}

var f = new foo();
f.bar2(f.bar1);

console.log(this) 的结果如何/为什么会是“Window”?我想不管你如何在这里调用一个类的公共函数,“this”应该总是指“foo”。

还有什么是避免这种错误的正确方法?

谢谢

4

1 回答 1

1

当你这样做时f.bar2(f.bar1),你将 bar1 的引用传递给 bar2;在 bar2 内部,它只被称为“func”,与 f 的连接丢失。的值this是在调用函数时动态确定的。如果您调用 f.bar1(),这将是 f,但是当您调用 func() 时,它是未定义的,并且将回退到全局对象(窗口)。

之前已经解释如下:

基本规则是,这将是全局对象,除非:

  • 该函数被称为对象方法(然后 this 将是对象),或者
  • 该函数被称为构造函数,带有 new 运算符(在这种情况下, this 将指向正在构造的新对象)

避免这种情况的一种方法是创建一个绑定函数并传递它:

f.bar2(f.bar1.bind(f));

请注意,旧版浏览器不支持 Function.prototype.bind,因此您可能需要一个 polyfill(在MDN上有一个可用的)。

在您提供的简单场景中,您可以执行 elclanrs 在他的评论中建议的操作,因为目标 this 在 bar2 中可用:

func.call(this);
于 2013-05-06T02:49:25.103 回答