JS 中的箭头和词法作用域

Arrow and Lexical Scope in JS

给定以下代码:

const outter = {
  inner: {
    laughter: "hahaha",
    laugh: () => {
      console.log(this) //`this` is window
    }
  }
}

const x = {
  test: function () {
    const laugh = outter.inner.laugh
    console.log(this) //`this` is x
    laugh()
  }
}

x.test()

我希望 laugh 方法中的 this 等于 x - 因为我们正在从 x 调用 laugh

在我们调用 laugh 的范围内,this 等于 x - 所以很奇怪 this箭头方法的变化,它应该遵循词法范围。

(注意,即使我们将 laugh 更改为普通函数,非箭头,this 仍然是 Window - 但这是有道理的)

谁能解释为什么 laugh 里面的 thisWindow

谢谢

箭头函数:

  • 没有this.
  • 没有arguments.
  • 不能用new调用。
  • 他们也没有super.

箭头函数没有“this”

如果访问this,则从外部取。

const outter = {
  inner: {
    laughter: "hahaha",
    laugh: () => {
      console.log(this) // the outer `this` is window.
    }
  }
}

阅读更多here

根据为 Firefox 实现箭头功能的人 Jason Orendorff 的说法 (here):

Arrow functions do not have their own this value. The value of this inside an arrow function is always inherited from the enclosing scope.

箭头函数不是在调用时赋值,而是在定义时赋值。

在您的示例中,laugh 属性 的箭头函数将绑定到其定义范围内的 this,在您的示例中为 window.

更新

OP 在评论中指出,由于箭头函数是在 outter [原文如此] 对象的内部 属性 中找到的,因此它应该选择该对象的范围。从表面上看,应该是这样

需要注意的是,在创建对象时,JS 必须从内到外分配 属性 值。换句话说,inner 对象字面量首先被创建,此时 outter 的上下文甚至还不存在!。因此,由于箭头函数在创建时就已绑定,因此 outter.inner.laugh 方法的函数与它所在的上下文绑定;在 创建 outter.inner 时,那将是 window.