The question is directed at people who have thought about code style in the context of the upcoming ECMAScript 6 (Harmony) and who have already worked with the language.
Arrow functions - most widely used ES6 feature so far ...
Usage : All ES5 functions should be replaced with ES6 arrow functions except in following scenarios:
Arrow functions should NOT be used:
this
/arguments
in a function
this
/arguments
of their own, they depend upon their outer context.constructor
this
.this
(which should be object itself).Let us understand some of the variants of arrow functions to understand better:
Variant 1: When we want to pass more than one argument to a function and return some value from it.
ES5 version:
var multiply = function (a,b) {
return a*b;
};
console.log(multiply(5,6)); //30
ES6 version:
var multiplyArrow = (a,b) => a*b;
console.log(multiplyArrow(5,6)); //30
Note:
function
keyword is NOT required.
=>
is required.
{}
are optional, when we do not provide {}
return
is implicitly added by JavaScript and when we do provide {}
we need to add return
if we need it.
Variant 2: When we want to pass ONLY one argument to a function and return some value from it.
ES5 version:
var double = function(a) {
return a*2;
};
console.log(double(2)); //4
ES6 version:
var doubleArrow = a => a*2;
console.log(doubleArrow(2)); //4
Note:
When passing only one argument we can omit parenthesis ()
.
Variant 3: When we do NOT want to pass any argument to a function and do NOT want to return any value.
ES5 version:
var sayHello = function() {
console.log("Hello");
};
sayHello(); //Hello
ES6 version:
var sayHelloArrow = () => {console.log("sayHelloArrow");}
sayHelloArrow(); //sayHelloArrow
Variant 4: When we want to explicitly return from arrow functions.
ES6 version:
var increment = x => {
return x + 1;
};
console.log(increment(1)); //2
Variant 5: When we want to return an object from arrow functions.
ES6 version:
var returnObject = () => ({a:5});
console.log(returnObject());
Note:
We need to wrap the object in parenthesis ()
otherwise JavaScript cannot differentiate between a block and an object.
Variant 6: Arrow functions do NOT have arguments
(an array like object) of their own they depend upon outer context for arguments
.
ES6 version:
function foo() {
var abc = i => arguments[0];
console.log(abc(1));
};
foo(2); // 2
Note:
foo
is an ES5 function, with an arguments
array like object and an argument passed to it is 2
so arguments[0]
for foo
is 2.
abc
is an ES6 arrow function since it does NOT have it's own arguments
hence it prints arguments[0]
of foo
it's outer context instead.
Variant 7: Arrow functions do NOT have this
of their own they depend upon outer context for this
ES5 version:
var obj5 = {
greet: "Hi, Welcome ",
greetUser : function(user) {
setTimeout(function(){
console.log(this.greet + ": " + user); // "this" here is undefined.
});
}
};
obj5.greetUser("Katty"); //undefined: Katty
Note:
The callback passed to setTimeout is an ES5 function and it has it's own this
which is undefined in use-strict
environment hence we get output:
undefined: Katty
ES6 version:
var obj6 = {
greet: "Hi, Welcome ",
greetUser : function(user) {
setTimeout(() => console.log(this.greet + ": " + user));
// this here refers to outer context
}
};
obj6.greetUser("Katty"); //Hi, Welcome: Katty
Note:
The callback passed to setTimeout
is an ES6 arrow function and it does NOT have it's own this
so it takes it from it's outer context that is greetUser
which has this
that is obj6
hence we get output:
Hi, Welcome: Katty
Miscellaneous:
We cannot use new
with arrow functions.
Arrow functions do Not have prototype
property.
We do NOT have binding of this
when arrow function is invoked through apply
or call
.