“如何”;这";在Javascript的回调中查找
我对以下情况感到困惑:“如何”;这";在Javascript的回调中查找,javascript,callback,this,Javascript,Callback,This,我对以下情况感到困惑: 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(此)的结果如何/为什么会是“窗口”?我想不管你们怎么称呼一个类的公共函数,“thi
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”应该总是指“foo”
还有什么是避免这种错误的正确方法
谢谢当您执行f.bar2(f.bar1)
时,您正在将bar1的引用传递给bar2;在bar2内部,它只被称为“func”,并且与f的连接丢失。如果调用f.bar1(),这将是f,但当调用func()时,它是未定义的,并且将返回到全局对象(窗口)
我的报告如下:
基本规则是,这将是全局对象,除非:
- 函数被称为对象方法(那么这将是 对象),或
- 该函数作为构造函数调用,使用新 运算符(在这种情况下,这将指向正在创建的新对象) 建造)
f.bar2(f.bar1.bind(f));
请注意,较旧的浏览器不支持Function.prototype.bind,因此您可能需要一个polyfill(上有一个可用的)
在您介绍的简单场景中,您可以按照elclanrs在其评论中的建议进行操作,因为bar2中提供了这一目标:
func.call(this);
这些规则与任何其他函数调用没有区别(请参阅)
Function.prototype.bind
(或模拟)在这里很有用,一般闭包也一样。我认为,您可以使用func.apply(this)
来获得预期的行为。func.call(this)
应该可以。@WaleedKhan但这是一种特殊情况,在这里特别有效,因为执行bar2
时的ThisBinding是“expected”。这个关键字在js中是一个相当复杂的问题。它包括:窗口对象、原型、调用/应用方法,可能还有更多。我推荐这本书:javscript enlightment。我认为非常有用