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
- 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);
- 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 correctthis
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
- 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
-
We can't use arrow functions in Generators as using them in Generators will throw Error.
-
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. ;)