JavaScript回调函数中如何查找“this”

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"。

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

谢谢


规则与任何其他函数调用没有区别(请参见https://dev59.com/tGQo5IYBdhLWcg3wBLjy)。`Function.prototype.bind`(或模拟)在这里可能很有用,通用闭包也是如此。 - user2246674
你可以使用 func.apply(this) 来获得预期的行为,我认为。 - Waleed Khan
func.call(this) 应该可以。 - elclanrs
@WaleedKhan 但这是一个特殊情况,它仅在此处起作用,因为执行 bar2 时的 ThisBinding 是“预期的”。 - user2246674
在 JavaScript 中,“this” 关键字是一个相当复杂的问题。它涉及到 window 对象、原型、call/apply 方法,可能还有其他内容。我推荐这本书:《JavaScript Enlightenment》。我认为它非常有帮助。http://www.javascriptenlightenment.com/JavaScript_Enlightenment.pdf - Herrington Darkholme
请查看我之前回答的相关问题:https://dev59.com/c2Yr5IYBdhLWcg3wuciw#13441628 - slebetman
1个回答

1
当你执行 f.bar2(f.bar1) 时,你正在将 bar1 的引用传递给 bar2;在 bar2 中,它只被称为 "func",与 f 的连接已经断开。在函数调用时,this 的值是动态确定的。如果你调用 f.bar1(),这个 this 将是 f,但当你调用 func() 时,它是 undefined,并且会回退到全局对象(window)。
我之前已经 解释过了:
基本规则是,除非:
- 函数作为对象方法被调用(此时 this 将是该对象),或 - 函数被用 new 运算符调用作为构造函数(此时 this 将指向正在构造的新对象)
否则,this 将是全局对象。避免这种情况的一种方法是创建绑定函数并传递它:
f.bar2(f.bar1.bind(f));

请注意,旧浏览器不支持Function.prototype.bind,因此您可能需要使用polyfill(MDN上有一个可用的)。
在您提供的简单场景中,您可以按照elclanrs在评论中建议的那样操作,因为目标this在bar2内是可用的。
func.call(this);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接