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
里面的 this
是 Window
?
谢谢
箭头函数:
- 没有
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
.
给定以下代码:
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
里面的 this
是 Window
?
谢谢
箭头函数:
- 没有
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
.