Javascript setTimeout中的箭头函数不';不要把窗户设成这样

Javascript setTimeout中的箭头函数不';不要把窗户设成这样,javascript,this,Javascript,This,我有一些由装饰器分配的对象的方法(函数f和ms就是从这里获得的) “this”在这里指的是对象。但是setTimeout的“this”是窗口,而不是那个对象。如果一个箭头函数的“this”是按词法提取的,那么为什么它不是从setTimeout提取的呢?毕竟,在以下代码中: let user = { firstName: "Ilya", sayHi() { let arrow = () => alert(this.firstName); arrow

我有一些由装饰器分配的对象的方法(函数f和ms就是从这里获得的)


“this”在这里指的是对象。但是setTimeout的“this”是窗口,而不是那个对象。如果一个箭头函数的“this”是按词法提取的,那么为什么它不是从setTimeout提取的呢?毕竟,在以下代码中:

let user = {
  firstName: "Ilya",
  sayHi() {
    let arrow = () => alert(this.firstName);
    arrow();
  }
};

user.sayHi(); // Ilya
“this”取自上述函数。那么,如果在第一种情况下该函数是setTimeout,为什么两种情况不一样呢?我认为这可能与函数在一种情况下作为参数传递有关,而在另一种情况下作为局部变量传递有关,但在词汇环境中这不也是一样的吗

为什么会有差异?

此外,为了验证这一点:

let obj = {name : "Jeff"};
let obj2 = {name : "Bart", fun2 : function(fun){fun();}};

obj.name2 = obj2.fun2(() => alert(this.name));
但现在我没有收到“巴特”的警报,而是一个空字符串。当我将“name”替换为length时,我只得到0,“this”表示窗口

为什么这不能按预期工作?

如果一个箭头函数的“this”是按词法提取的,那么为什么它不是从setTimeout提取的呢

词法意味着作用域取自函数声明的位置,而不是传递到的位置

在函数内部,其值取决于函数的调用方式

在函数中,您已将
窗口
对象传递给setTimeout

如果更改函数并仅传递参数,则将获得对象:

function f() {
  console.log(this);
};

function a (){
  setTimeout(() => f.apply([1]), 1000); // here this = [1]
}

a();  // Array [1]

您已将一个箭头函数作为回调函数传递给
setTimeout
,因此此回调中的
this
将引用封闭范围内的
this
,该范围是对象的方法。函数使用定义它们的范围,而不是调用它们的范围。传递给
setTimeout
的箭头函数未在
setTimeout
中定义。这里的“this”指的是对象。但是setTimeout的“this”是窗口,
this
从未设置为任何对象,而它指向的是窗口对象。我的意思是,setTimeout是窗口的一种方法,因此,我认为arrow函数将在setTimeout内声明,从而导致setTimeout作为'this'值的来源,但函数不是在正在执行的setTimeout内声明吗?它不是在
setTimeout
内声明的。您没有查看
setTimeout
的源代码。它在函数表达式中声明,该表达式从第一个代码块的第1行开始,然后作为参数传递给
setTimeout
。这是否意味着作为参数传递的任何箭头函数都不会声明为执行函数的局部变量,而是在它之前?是,这正是我所说的。函数表达式也是这样吗?
function f1() {
  return this;
}

// In a browser:
f1() === window; // true
function f() {
  console.log(this);
};

function a (){
  setTimeout(() => f.apply([1]), 1000); // here this = [1]
}

a();  // Array [1]