11

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?

2
  • 1
    In your example this will be undefined if you want to get the value of name either use the normal function syntax or reference the object name so it's person.name Commented May 20, 2017 at 1:40
  • 7
    An Object literal doesn't create an enclosing context. Only the body of a normal function does. Commented May 20, 2017 at 6:37

3 Answers 3

16

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.

Sign up to request clarification or add additional context in comments.

Comments

9

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();

Comments

4

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.