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:
1. When we want function hoisting
– as arrow functions are anonymous.
2. When we want to use `this`/`arguments` in a function
– as arrow functions do not have `this`/`arguments` of their own, they depend upon their outer context.
3. When we want to use named function
– as arrow functions are anonymous.
4. When we want to use function as a `constructor`
– as arrow functions do not have their own `this`.
5. When we want to add function as a property in object literal and use object in it
– as we can not access `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");
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`.