这些代码块在JavaScript中是如何工作的?

这些代码块在JavaScript中是如何工作的?,javascript,Javascript,让我们看看例子: 第一名: var user = { firstName: "John", sayHi: function() { alert( this.firstName ); } }; setTimeout(function() { user.sayHi(); // John }, 1000); var user = { firstName: "John", sayHi: function() { alert( this.firstName ); }

让我们看看例子:

第一名:

var user = {
  firstName: "John",
  sayHi: function() {
  alert( this.firstName );
  }
};

setTimeout(function() {
  user.sayHi(); // John
}, 1000);
var user = {
  firstName: "John",
  sayHi: function() {
  alert( this.firstName );
  }
};

setTimeout(user.sayHi, 1000);// undefined
秒:

var user = {
  firstName: "John",
  sayHi: function() {
  alert( this.firstName );
  }
};

setTimeout(function() {
  user.sayHi(); // John
}, 1000);
var user = {
  firstName: "John",
  sayHi: function() {
  alert( this.firstName );
  }
};

setTimeout(user.sayHi, 1000);// undefined

为什么在第二个示例中未定义?这是如何工作的?

当您将函数引用传递给
设置超时
函数时,传递的函数引用将在
窗口
的范围内执行。所以
window.firstName
将是
未定义的
,因为在
window
对象中没有这样的属性

var user = {
  firstName: "John",
  sayHi: function() {
  alert( this.firstName );
  }
};

setTimeout(user.sayHi.bind(user), 1000);
因此,正如您在上面的代码中所看到的,您必须显式地将作用域绑定到函数引用。你也可以用传统的方法,就是使用一个匿名函数,如下所示

setTimeout(function(){ user.sayHi(); }, 1000);

谢谢,但我不明白你的例子是如何使用匿名函数的?如何保存上下文?@JimButton使用匿名函数,它将成为一个闭包。我指的是对象用户。但是对于第一种情况,内部setTimeout将调用传递的函数引用,如
reference.call(scope)
,其中scope将是未被重写的窗口。因此,此.firstName类似于window.firstName。谢谢您的帮助!