I thought I understood the relationship between this
and arrow functions but the following snippet is making me question my understanding.
let person = {
name: 'Jim',
sayName: () => {
console.log(this.name);
}
};
person.sayName();
I understand that arrow functions capture the this
value of the enclosing context. I was expecting this
would be the object but instead it is Window
.
Can someone help me understand why this is the case?
Remember what we said about the arrow functions using this ?. this , inside the arrow function, implies that the function does not have a this value of its own. They don't define their own context since it doesn't have its own this context. They inherit that from the parent scope whenever you call this .
Arrow Functions as Object Methods However, since an object does not create a new lexical scope, an arrow function will look beyond the object for the value of this . Since the object does not create a lexical scope, the arrow function method looks for this in the outer scope– Window in this example.
It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.
Arrow functions don't have their own bindings to this , arguments or super , and should not be used as methods. Arrow functions don't have access to the new.target keyword. Arrow functions aren't suitable for call , apply and bind methods, which generally rely on establishing a scope.
Your understanding of arrow functions is mostly correct: Arrow functions have a lexical this
and its value within the arrow function is determined by the surrounding scope.
You probably assume that this
gets a different value within the person
object literal. This is not the case.
So let's see what this
refers to in your (global) scope:
console.log(this === window); // true
let person = {
name: 'Jim',
test: console.log(this === window), // true
sayName: () => {
console.log(this === window); // true
}
};
person.sayName();
As you can see, when the arrow function assigned to sayName
is created, this
refers to the window
object.
TLDR;
Think of it this way, "if I used non arrow function, what would be this
" From that you can then recall that this
in an arrow function would be the more outer scope this
compared to its counterpart.
Example
let arrow = {
test: () => {
console.log('arrow: this === window...', this === window);
}
};
let nonarrow = {
test: function() {
console.log('non-arrow: this === window...', this === window);
}
};
arrow.test()
nonarrow.test();
There is no binding of "this", so here is a working version of what you tried:
let person = {
name: 'Jimmy the Greek',
sayName: (obj) => {
console.log(obj.name);
}
};
person.sayName(person);
More to read on Mozilla DEV.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With