Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“如何”;这";在Javascript的回调中查找_Javascript_Callback_This - Fatal编程技术网

“如何”;这";在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。我认为非常有用