ES6 Arrow-Functions vs ES5 Functions

When we say Javascript is mostly about functions, it's quite a valid statement in itself. Functions are key components of Javascript. In ES6, our very own generous committee aka TC39 introduced a succinct and better way of writing function expressions called arrow functions, also known as lambda functions.

Syntactical Differences

There is a noticeable difference between the syntax of es5 functions and es6 arrow functions.

//es5 functions
    const printHelloWorld = function() {
        console.log('Hello World');
    }
//es6 arrow functions
    const printHelloWorld = () => console.log('Hello World');

In the above syntax we can put the curly braces {} after the token=>. Omitting it will ensure that we are implicitly returning the value from the function. In this case, the execution of console.log('Hello World') is our implicit return statement, which doesn't return anything rather prints Hello World on the console.

Conceptual Differences

Conceptually, there is a huge difference between arrow functions and es5 functions.

The this context in the es5 functions is dynamic and refers to object, which is executing our function. For example, if we execute the function in global context then global object aka window in browser will be our this.

Whereas, the this context of our fat arrow functions is lexically bound ( aka while defining the function).

Advantages

  1. Array manipulation and ease in functional programming are two of the major selling points of arrow functions.
    const fruitesBasket = [
        {
            name: 'apple',
            quantity: 10 
        },
        {
            name: 'oranges',
            quantity: 13
        },
        {
            name: 'bananas',
            quantity: 17
        }
    ]
    // Now we will filter the objects
    //es5 way 
    const filteredBasket = fruitesBasket.filter(function(item) {
        return item.quantity > 12;
    })

    //es6 way
    const filteredBasket = fruitesBasket.filter((item) => item.quantity > 12);
  1. They reduce the confusion surrounding the this keyword. In code with multiple nested functions, it can be difficult to keep track of and remember to bind the correct this context. In ES5, you can use workarounds like the .bind method (which is slow) or can create a closure using const self = this; But with arrow functions, we don't need it as they retain the scope of the environment where the functions are defined.

Pitfalls

  1. We can't use the arrow functions as Constructor functions.

For example

const Constructor = (name) => {
    this.name = name
}

Now if using the above constructor, if we try to create an object.

const newObj = new Constructor('abc');
console.log(newObj.name) //undefined 

We are going to get undefined, why? Remember, fat arrow functions have the lexical scope so in this case, the this in the constructor is referring to the window object. Hence a new property will be created on window rather than your object.

console.log(name) //abc
  1. We can't use arrow functions in Generators as using them in Generators will throw Error.

  2. While for some, using the new syntax is more fun and easier way to express the code, for a few class of developers it's a bane, as they now have to remember this context in lexical scope as well.

Conclusion

Es6 arrow functions are definitely a positive step towards a cleaner and succinct way of writing code. Although we have to remember this new this context, it has its own advantages over its counterparts in my honest opiniom. That's it for this time. Don't forget to comment your views on this blog. ;)