Given the following code:
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()
I would expect the this
inside of the laugh
method to be equal to x
- because we're invoking laugh
from x
In the scope where we invoke laugh
, this
is equal to x
- so it's strange that this
changes in the arrow method, which should follow lexical scope.
(note, even if we change laugh
to a normal function, non-arrow, this
is still Window
- but that makes sense)
Can anyone explain why this
inside of laugh
is Window
?
Thanks
According Jason Orendorff, the guy who implemented arrow functions for Firefox, wrote the following (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.
The arrow function is not assigned when invoked, rather, when it's defined.
In your example, the arrow function of the laugh
property will be bound to the this
in the scope it was defined in, which in your example is window
.
The OP remarked in the comments that since the arrow function is found inside an inner property of the outter
[sic] object, it should pick up the scope of that object. Superficially, this is the way it should be.
The caveat is that when creating objects, JS has to assign the property values from the inside out. In other words, the inner
object literal is created first, at a time when the context of outter
doesn't even exist yet!. And, therefore, since arrow functions get bound at the time of creation, the function for the outter.inner.laugh
method is being bound with the context that it is found in; at the time of creating outter.inner
, that would be window
.