loading...

What does it mean "Arrow function will not rebind "this"?"

moz5691 profile image Chan Ho Ahn Updated on ・1 min read

What does it mean "arrow function won't rebind "this"" ?

How to reference to the person object inside from callback function? The referenced callback function is "setTimeout()" in the following example.

[Code #1 ]
const person = {
  walk() {
    setTimeout(function() {
      console.log('this', this);
    }, 1000);
  }
};
person.walk();

The following is the result from Code #1.

[Code #1 Result]
index.js:4 this 
    1. Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

As you run the above example, "this" returns Window object. It is definitely not what we want to see. "this" inside callback function references to outside of person object in this case. Even if "strict mode" is enabled we still see the same problem. The reason for this unexpected behavior is "this" in Javascript runs differently from other languages. "this" in Javascript rebind "this" inside the callback function which means "this" points to "Window" object as it is passed into the callback function.

There are two different ways to address this problem. [Code #2] and [Code #3] show an old way and a new way, respectively.

If we don’t want to use "arrow function in ES6", we can still use an old way to fix this problem. We can pass "this" to another const value such as "self" to store the state of "this" to "self" before invoking callback function. "self" in the callback function stores the prior state of "this" such that "this" still can be updated inside of the callback function while "self" contains the previous state of "this". Obviously, "self" stores "person" object with walk() method in it.

[Code #2]
const person = {
  const self = this;
  walk() {
    setTimeout(function() {
      console.log('self', self);
    }, 1000);
  }
};
person.walk();
[Code #2 Result ]
this 
    1. {walk: ƒ}
        1. walk: ƒ walk()
            1. arguments: null
            2. caller: null
            3. length: 0
            4. name: "walk"
            5. prototype: {constructor: ƒ}
            6. __proto__: ƒ ()
            7. [[FunctionLocation]]: index.js:2
            8. [[Scopes]]: Scopes[1]
        2. __proto__: Object

The arrow function (=>) helps to resolve "this" rebinding. ES6 Arrow function will not rebind "this" inside the callback function. If we change the callback function into arrow function, "this" is inherited into the callback function. Simply change the callback function into arrow function... That's all you need to do.

[Code #3 ]
const person = {
walk() {
    setTimeout(() => {
        console.log('this', this);
    }, 1000);
    }
};
person.walk();
[Code #3 Result]
    1. {walk: ƒ}
        1. walk: ƒ walk()
            1. arguments: null
            2. caller: null
            3. length: 0
            4. name: "walk"
            5. prototype: {constructor: ƒ}
            6. __proto__: ƒ ()
            7. [[FunctionLocation]]: index.js:2
            8. [[Scopes]]: Scopes[1]
        2. __proto__: Object

Hope that this post can help understand ES6 arrow function and how it solves "this" rebinding in callback function.

Posted on Oct 26 '18 by:

Discussion

markdown guide