I have two cases and I am confused with the output I am getting.
Case 1 :
let x = {
b: 5,
y: function a() {
return function() {
return () => {
console.log(this);
}
}
}
}
x.y()()();
On running x.y()()()
I am getting Window
object as output but according to arrow function's definition, the output should have been its parent function.
Case 2 :
let x = {
b: 5,
y: function a() {
return () => {
console.log(this);
}
}
}
x.y()();
If I remove one level of nesting which is a basic example then on running x.y()()
, I am getting object x
as output.
Can you please explain why exactly am I getting these output?
The this
inside a function is determined by its calling context, and by whether the function is an arrow function or not.
With an arrow function, this
is always inherited from the outer scope.
If the function being called is a full function
and that function is being called as a property as an object (eg obj.foo()
), then the calling context, the this
inside the foo
function, is obj
.
If the function being called is a full function
but is standalone - that is, not a property of an object - then there is no calling context, and this
inside the function will be undefined
or the global object.
With
let x = {
b: 5,
y: function a() {
return function() {
return () => {
console.log(this === window);
}
}
}
}
x.y()()();
The this
is what the returned function's this
is - that is, the calling context for the function invoked here:
x.y()()
The function being invoked is not part of an object - it's a standalone function expression which was created from the invocation of a prior function on an object, equivalent to:
(x.y())()
So, there is no calling context, and this
is the global object.
In contrast, in case 2, the closest ancestor function
being called is the a
function on the y
property of the object, and this function is called with a calling context:
x.y()()
^^^^^
Above, y
is called with a calling context of x
, so this
is x
inside the a
function.