ES6 arrow functions
Arrow function (sometimes called fat arrow function) introduced in ECMA 2015 spec is not only an awesome way to write functions but also solves some common problems associated with traditional functions.
Syntax:
/* Traditional Function syntax */
var add1 = function(a, b) {
return a + b;
}/* arrow function syntax */
var add2 = (a, b) => {
return a + b;
}/*
If the function's body has only the return statement, it can be written inline as follows
*/
var add3 = (a, b) => a + b;/* A arrow function to increment a number */
var inc1 = (a) => a + 1;/*
If the function has only one input argument, it can be written inline as follows.
*/
var inc2 = a => a + 1;/* Arrow functions can be invoked just like normal functions */
add1(1, 2); // 3
add2(1, 2); // 3
add3(1, 2); // 3inc1(1); // 2
inc2(1); // 2
How are arrow functions different from traditional function
Other than new syntax, arrow functions does not bind this to the global object like their counterparts .
NOTE: Before you continue, make yourself familiar with this and constructor functions in JS.
‘ this ’ Binding :
Let us try to create a constructor function for Person object that creates the Object after a time delay of 1 Sec.
function Person(firstName, lastName) {
this.firstName = firstName;
setTimeout(function() {
this.lastName = lastName;
}, 1000);
}var p = new Person('Pavan', 'varma');
Now the object that is created is {firstName: 'Pavan'}
, not exactly what we Intended. This behavior is counter intuitive in Object Oriented style programming and is caused due to this binding of anonymous callback function to global. This is generally overcome by using additional workarounds (using a reference to this or bind()).
/* using a reference to function's this */
function Person1(firstName, lastName) {
var that = this;
that.firstName = firstName;
setTimeout(function() {
that.lastName = lastName;
}, 1000);
}/* using bind to set proper this binding */
function Person2(firstName, lastName) {
this.firstName = firstName;
var assignLastName = (function() {
this.lastName = lastName;
}).bind(this); setTimeout(assignLastName, 1000);
}
Both the above methods work, producing the correct Object {firstName: 'Pavan', lastName: 'Varma'}
. Now using ES6 arrow functions it can be written as follows.
function Person(firstName, lastName) {
this.firstName = firstName;
setTimeout(() => {
this.lastName = lastName;
}, 1000);
};
A arrow function never has it’s own this context, so this has the original meaning from the surrounding code (lexical scope). Thus letting you get the expected output.
A arrow function never has it’s own this context, and it cannot be bound to a object using call( ), apply( ) or bind( ). Thus arrow functions are truly anonymous.
When you cannot use arrow functions :
- Since there is no this binding, arrow functions cannot be used as constructor functions.
- Named functions(function fun_name() {}) cannot be created using arrow functions.
- Arrow functions cannot be used as object methods.
var myObj = {
a: 1,
b: 2,
c: () => {
return this.a + this.b; // does not work as expected
}
}
- To avoid this limitation, an alternative ES6 syntax for declaring object methods can be used.
var myObj = {
a: 1,
b: 2,
c() {
return this.a + this.b; // works as expected
}
}
- Also arrow functions cannot be used to define methods on Object prototype, in this case traditional functions are our only option.
Except in the above cases, arrow functions can be used as replacement for traditional functions.
Lastly, arrow functions make for compact and concise code, scope safety and most importantly true anonymous functions with lexical scoping.