You-dont-know-js: ES6 & Beyond, this in arrow function

Created on 15 Jun 2016  路  9Comments  路  Source: getify/You-Dont-Know-JS

Hello,
I have a confusion regarding the this for arrow function.

var controller = {
    makeRequest: (..) => {
        // ..
        this.helper(..);
    },
    helper: (..) => {
        // ..
    }
};

controller.makeRequest(..);

Although we invoke as controller.makeRequest(..), the this.helper reference fails, because this here doesn't point to controller as it normally would. Where does it point? It lexically inherits this from the surrounding scope. In this previous snippet, that's the global scope, where this points to the global object. Ugh.

It was explained by you, but I am finding it confusing and a little hard to understand why or should I say how the this is being taken from global scope!

Like, if the value of this doesn't depend on the call site for arrow functions, then how come here it is pointing to the global object?

Thanks,
Anirudh

question

Most helpful comment

yes and yes. only regular functions (and the global scope) have a lexical 'this'.

All 9 comments

if the value of this doesn't depend on the call site for arrow functions

it doesn't. it behaves based on the declaration site of the arrow function, not the call site. and it's the manner of the call site, not the location of the call site, that would matter anyway.

in this example, the call site says controller.makeRequest(). if that call site determined the this, then controller would be this because of the _implicit binding_ rule. but since this isn't controller, we know the call site is irrelevant. the arrow function is declared in the global scope. that's why this points to the global scope.

the call site says controller.makeRequest(). if that call site determined the this, then controller would be this because of the implicit binding rule.

Why doesn't the call site doesn't determine this to be the controller?

How come the implicit binding rule is being overridden?

More info: https://blog.getify.com/arrow-this/

Summary: arrow functions don't have their own this, so there's nothing to rebind.

So, if this is being looked up the scope.

In implicit binding the obj a will be printed.

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

obj.foo(); // 2

However, if I try the same thing, with arrow function, it refers to the global object.

var foo2 = () => {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo2
};

obj.foo(); // undefined

Why doesn't it refers to the this of obj and refer to the global a?

because obj.foo is just a reference to the same arrow function, not a regular function. no reference to the arrow function, no matter how it's obtained or called, can bind a this inside the arrow function... the arrow function will always look to its lexical scope lookup.

Ok, I understood the part that since arrow functions dont have a this of its own, it doesn't have anything to which it is binded. However, I have two question.

  1. When we declare foo as a regular function, and call by obj.foo is the reference of foo passed during execution, and during execution of foo the JS creates a this which is binded to the object obj?
  2. During lexical scope lookup for this why does't it bum into the this of the object? Does it mean that objects declared using object literal does not have a this of their own?

yes and yes. only regular functions (and the global scope) have a lexical 'this'.

awesome!!! Got it!!!
Thanks for your time!!

Was this page helpful?
0 / 5 - 0 ratings