我在以下情况中感到困惑:
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”?我想无论你怎么称呼一个类的公共功能,“这个”应该总是指“foo”。
还有什么是避免这种错误的正确方法?
谢谢
答案 0 :(得分:1)
执行f.bar2(f.bar1)
时,您将bar1的引用传递给bar2;在bar2中,它只被称为“func”,与f的连接丢失了。 The value of this
is determined dynamically when the function is invoked。如果你调用f.bar1(),这将是f,但是当你调用func()时,它是未定义的,并将回退到全局对象(窗口)。
基本规则是,除非:
,否则这将是全局对象
- 该函数被称为对象方法(然后这将是 对象),或
- 使用new将函数作为构造函数调用 运算符(在这种情况下,这将指向新对象 构造)
避免这种情况的一种方法是创建绑定函数并传递:
f.bar2(f.bar1.bind(f));
请注意,旧浏览器不支持Function.prototype.bind,因此您可能需要填充(MDN上有一个填充)。
在你提出的简单场景中,你可以做elclanrs在评论中建议的内容,因为bar2中可以使用这个目标:
func.call(this);