Monday, July 30, 2018

Javascript ES6 - lexical scope of this

In Javascript every function brings its own 'this' context. The situation becomes difficult to work with when there are many functions inside function which complicates the context of 'this'. The ES6 fat arrow (=>) passes the lexical scope of parent 'this' to all child functions -

Example:
function parentFunction(){
    this.add = 0;
    this.addAnother = function(){
    this.addOne = setTimeout(function(){
        console.log(++this.add);
        }, 1000)
    }
} 

var funcObj = new parentFunction();
funcObj.addAnother(); // NaN  

It outputs to 'NaN' because the 'this' context here 'console.log(++this.add);' is scoped to setTimeout function.

To avoid this, the ES5 solution is to use the classic 'var that = this' -
function parentFunction(){
    this.add = 0;
    var that = this;
    this.addAnother = function(){
    this.addOne = setTimeout(function(){
        console.log(++that.add);
        }, 1000)
    }
} 

var funcObj = new parentFunction();
funcObj.addAnother();  

Now, this works perfectly fine, but the new ES6 fat arrow works even better by passing the lexical scope of parent 'this' to all child functions -
function parentFunction(){
    this.add = 0;
    this.addAnother = () => {
    this.addOne = setTimeout(() => {
        console.log(++this.add);
        }, 1000)
    }
} 

var funcObj = new parentFunction();
funcObj.addAnother();  

The traditional ES5 'this' creates a new scope of 'this' in each function which is why we were getting the 'NaN' because the 'this' in setTimeout function was scoped to the setTimeout function alone.

With the fat arrow, the 'this' in setTimeout refers to the lexical scope of parent 'this'.




No comments:

Post a Comment