Arrow Functions
One of the most exciting and important features of ES6 is the Arrow Functions. Before we get into the details of the arrow functions, let’s see 2 variants of the functions in javascript. The first variant is the regular function which we can define as shown below.
function addTwoNumbers(a, b) {
return a + b;
}
The other variant is the function expression, this variant allows us to assign the reference to a variable. This variant looks as shown below.
const addTwoNumbers = function (a, b) {
return a + b;
};
In the above example, we’re creating an anonymous function and assigning it to a variable.
The arrow function allows us to write the function expression in a concise way. Basically they are anonymous functions only but with a different syntax. For example, the above function can be written as an arrow function as shown below. There are more ways to define the above function as an arrow function but we’ll see them later. Let’s focus on the simplest and more similar way.
const addTwoNumbers = (a, b) => {
return a + b;
};
This is the same as the function expression we’ve defined earlier but with a different syntax. This is called an arrow function (since it contains the arrow! this arrow is often referred to as the fat arrow). In some other programming languages like C# and java, it is referred to as a lambda expression. This anonymous function can be read as the following or at least that’s how I read it.
The parameters a and b go to a function expression that returns a+b.
Though the earlier function expression and the arrow function look similar except the syntax and behaves similarly in some ways; there are some differences between them that we’ll see later.
Why should we use arrow functions
Now that we have seen what are arrow functions, let’s see why they exist and what advantages they offer. Following are the 2 top most advantages.
- Shorter syntax; though the example I have given above does not justify this advantage, we’ll see some more examples in which the arrow function results in a shorter syntax.
- It binds this to the surrounding code’s context.
Variants of arrow functions
The arrow functions have some variants based on the parameters and function body to make the function more concise. Let’s look at them.
Parameter based variants
- No parameter or multiple parameters
If the function has no parameter or it has multiple parameters, then we have to use the parameter parentheses as shown in the following examples.
const addTwoNumbers = (a, b) => {
return a + b;
};const logCurrentTime = () => {
console.log(`Current time is ${new Date().toLocaleTimeString()}`);
};
2. A single parameter
If the function has exactly one parameter then it’s optional to have the parameter parentheses. So a function with only one parameter can be written in the following 2 ways. (They can be written in more than 2 ways based on the function body).
const logMessage = (message) => {
console.log(`Message : ${message}`);
};
The above function can be written without using parameter parentheses as shown below.
const logMessage = message => {
console.log(`Message : ${message}`);
};
Function body based variants
- Body just contains a single expression
If the function body just contains a single expression then the curly braces for the function body with the return keyword can be replaced by just parentheses without the return keyword. So the addTwoNumbers function that we defined earlier can be defined as shown below.
const addTwoNumbers = (a, b) => (a + b);
We don’t even need the parentheses for the function body in this case; so the same function can be written as shown below.
const addTwoNumbers = (a, b) => a + b;
However there is an exception. If the function returns an object literal then the body must have the parentheses as shown below.
const getDimensions = () => ({ width: 100, height: 50 })
2. Body contains at least one statement
If the function body contains at least one statement then the body must have the curly braces. And if the function needs to return the value then the body needs to return the value explicitly as shown below.
const addTwoNumbers = (a, b) => {
const sum=a+b;
console.log(`sum of ${a} and ${b} is ${sum}`);
return sum;
};
Here we need to use curly braces since the function has a statement “console.log(`sum of ${a} and ${b} is ${sum}`);”. And since we’re using this syntax, it does not return implicitly, so we need to write the return statement at the end if we want the function to return the value.
Behavior of this in arrow functions
As I mentioned earlier, there are some ways that arrow functions differ from regular functions. And one of the differences is the behaviour of this. In the regular function this depends on the context, in other words it depends on how the function is being called. On the other hand this in the arrow function depends where the function is defined.
Let’s see an example.
var width=2;
var height=3;
var square={width:5,height:5};
function calculateAreaRegular(){
console.log(this.width*this.height);
}
const calculateAreaArrow=()=>{
console.log(this.width*this.height);
}
calculateAreaRegular(); //logs 6
calculateAreaRegular.call(square); //logs 25
calculateAreaArrow(); //logs 6
calculateAreaArrow.call(square); //logs 6
In the above code snippet, we have defined the function to calculate the area of a shape in 2 different ways. One with the regular function expression and the other with the arrow function.
There are 3 global variables width, height, and square. And we’re calling both the functions twice; once with no arguments and once with the square object as an argument.
The output of the function call calculateAreaRegular(); will log 6 since here this refers to the window object. However when the function is called using call passing square as the argument; it logs 25 since here this refers to the square object. But in the case of the arrow function, both the calls log 6 since in both the cases this refers to the window object.
So when the calling context is important, using arrow function should be avoided. Another scenario where it should be avoided is when older browsers need to be considered that do not support arrow functions and there’s no option to use polyfill. I’ll cover how polyfill can be used for ES6 features in some other post. If you want to see whether the browser supports the arrow function, you can visit the following link.