Category Archives: ES6

ES6 + Arrow Function + Mystery with this

We have been using arrow function for quite some time in compile languages like C#, but the same is now available in java script.

An arrow function is short hand, we can leave off the function keyword and we can leave of the return statement. Even though it kind of short hand operator, but its main purposes is to get away from nuances of this keyword in javascript. First we will cover basics around arrow function then discuss nuances around this keyword.
Consider the following example

(function () {
    'use strict'
    var getName = () => "aamol";
    console.log(typeof getName);
})();

What will be the output? It is going to be function, so essentially we are declaring a function but in a short hand way. Now if we execute that function what will be the output, it would be “aamol” 

(function () {
    'use strict'
    var getName = () => "aamol";
    console.log(getName());
})();

So again as mentioned above we can leave off the return keyword in an arrow function, whatever expression is specified over there will get returned. Here is another example of arrow function

(function () {
    'use strict'
    var getName = lastName => "aamol" + " " + lastName;
    console.log(getName("gote"));
})();

So in case if we have one argument to the function then we can leave off the parenthesis. It will output “aamol gote”. Now in case if you have more than 2 parameters then we have 2 use parenthesis. Output would be the same “aamol gote”. 

(function () {
    'use strict'
    var getName = (firstName, lastName) => firstName + " " + lastName;
    console.log(getName("aamol", "gote"));
})();

Now there would be scenarios where you will have more than single expression, then how does the arrow function look like shown below, your arrow function should return some thing.

(function () {
    'use strict'
    var getName = (firstName, lastName) => {
        if (firstName && lastName) {
            return firstName + " " + lastName;
        }
        else if (firstName && !lastName) {
            return firstName;
        }
        else if (!firstName && lastName) {
            return lastName;
        }
        else {
            return null;
        }
    }
    console.log(getName("aamol", "gote"));
})();

As discussed above real purpose of arrow functions is to handle this key word within functions, “this” has always been confusing aspect of JavaScript and in ES6 arrow functions make it easier to understand. Consider following example what would be the output?

    document.addEventListener("click", function () {
        console.log(this)
    });

Output will be “#document” in chrome browser.

Whenever we have an event handler in java script, this gets set to the element that receives the event and this caused problems in ES5 because we could not get access to the context of the function. Now consider the same example with arrow function

'use strict'
document.addEventListener("click", () => console.log(this));

Output will be “#Window” in chrome browser.

We are in the global area over here and not in the context of a function so this refers to the context of code in which we running which is window a global object. So as long as we are using arrow functions this will not be set to the element that is getting the event it is going to be set to the context in the code which are running in.

Lets consider another example,

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function () {
        console.log(this);
    }
}
person.getName();

What would be the output, it would be person object
{age: 34, firstName: “aamol”, lastName: “gote”}

Now we will replace getName function with arrow function

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName:  () => console.log(this)
}
person.getName();

Output over here would be window object. If we were inside the function then we would get the function context

Lets take another example

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function(){
        return () => console.log(this)
    }
}
person.getName()();

Now in this case getName() is returning the function, so what would be the output, it would be person object, because it getName() is function and that is the context that we are working with and because we are returning the function, so this will be set to the context of invoice object.

Another important aspect for arrow functions is related to .bind, .call and .apply. Consider following example

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function(){
        return () => console.log(this)
    }
}

var person2 = {
    age: 36,
    firstName: "john",
    lastName: "doe",

}
person.getName().bind(person2)();

Output will be {age: 34, firstName: “aamol”, lastName: “gote”} and not person2 object. This is very important with arrow functions you cannot bind a new object to arrow functions. Javascript engine did not even throw the error, it just ignored the bind call. So when u are working with arrow functions you will not be able to change the value of this like in traditional javascript.

Like .bind similar scenario exist for .call and .apply.

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function(){
        return () => console.log(this)
    }
}

var person2 = {
    age: 36,
    firstName: "john",
    lastName: "doe",

}
person.getName().call(person2);

Output will be {age: 34, firstName: “aamol”, lastName: “gote”} and not person2

Same applies to .apply.

So in summary in case of arrow function .call, .bind and .apply are useless, you cannot change the value of this.

One more quirk to the arrow functions consider the following example

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: () 
        => console.log(this)
    
}
person.getName();

This is gives an syntax error “Uncaught SyntaxError: Unexpected token =>”
New line character is problem with arrow functions you cannot put the arrow symbol on to the new line.

Arrow functions do not have “prototype” property.

'use strict'
var getName = () => "aamol";
console.log(getName.hasOwnProperty("prototype"));

Output would be false.

Whenever you declare a function in javascript it will by default have the prototype property. So unlike ES% in ES6 if you declare an function with arrow symbol, we do not have access to prototype.