Arrow functions, or arrow function expressions, are another way of declaring functions in JavaScript. But, please note right from the outset, that the differences between regular functions and arrow functions don't end with just the syntax. In other words, arrow functions are not a syntactic sugar for regular functions rather they're treated differently by the compiler. In this section, we'll focus on the just the syntax of arrow functions.
Let's quickly see an example of an arrow function compared to an old-school function declaration.
function oldSchoolFunc(a, b, c) {
console.log(a, b, c);
return (a + b + c);
}
The same function above using the arrow function syntax would be:
const arrowFunc = (a, b, c) => {
console.log(a, b, c);
return (a + b + c);
}
So, the function
keyword was removed and an arrow =>
(equal sign followed by a 'greater than' sign) was introduced before the opening curly brace {
to convert the old-school syntax to an arrow function syntax. Also please note that the part that constitutes an arrow function is to the right of the assignment. The identifier arrowFunc
is just a variable that is being used to hold a reference to the arrow function so we can invoke it later.
When it comes to function definitions, we basically have two things to consider: the parameter list and the function body. We'll take these one by one and go through their different cases to see how an arrow function is written in each case. Remember, the starting point is always the same: remove the function
keyword and introduce the arrow =>
before the opening curly brace {
. Once you get used to the arrow function syntax though, you won't have to think in terms of the old-school syntax anymore.
Please note that I'm using the term "old-school" quite loosely here. This in no way implies that the arrow functions have "replaced" the original function declaration syntax. There are places where using an arrow function is better suited than a normal (non-arrow?) function and vice versa. There are situations where the use of arrow functions is even discouraged!
Cases for function's parameter list
Case 1: no parameters
function oldSchoolFunc() {
/* function body */
}
const arrowFunc = () => {
/* function body */
}
The empty parentheses are required in this case.
Case 2: Multiple parameters
function oldSchoolFunc(a, b, c) {
/* function body */
}
const arrowFunc = (a, b, c) => {
/* function body */
}
Case 3: Special case of exactly ONE parameter
If the function has exactly one parameter, we can let go of the parentheses ()
in the arrow function expression. Note that you can use the parentheses as well; your choice. In my opinion, using the parentheses makes for a more readable code.
function oldSchoolFunc(a) {
/* function body */
}
const arrowFunc1 = a => {
/* function body */
}
const arrowFunc2 = (a) => {
/* function body */
}
Both arrowFunc1
and arrowFunc2
are equivalent.
Cases for function's body
Case 1: Multi-line body
If the body of a function has more than one lines, nothing changes:
function oldSchool(a, b, c) {
// line 1
// line 2
}
const arrowFunc = (a, b, c) => {
// line 1
// line 2
}
Case 2: Special case of SINGLE-LINE body
If the body of a function has exactly one line, then:
- No need for the curly braces
- No need for the
return
keyword (if any)
function oldSchoolSum(a, b) {
return (a + b);
}
const arrowSum = (a, b) => (a + b);
If an arrow function has exactly one line and the curly braces are left out, the line is executed and its final value is returned by the function (called implicit return). Note that you can still use the return
keyword in this case but then curly braces are required. Taking the arrowSum
function above as an example:
const arrowSum = (a, b) => {
return (a + b);
}
๐ก just a tip
There is something to be said about the two special cases discussed above: exactly one parameter and single-line body. Go for the option that results in a more readable code. For example, even though we have the option, using parentheses even when there is only one parameter seems better because it feels more readable (in fact, the famous code formatter Prettier will enforce this as a rule). Similarly there are times when using the
return
keyword just looks more natural even if the function only has one line. Do not automatically go for the more concise option rather take a moment and decide which option will result in a more readable code.
More than just syntax
As mentioned at the start of this section, it isn't just the syntax that is affected when using the arrow functions. Arrow functions:
- don't have
this
- don't have
super
- can't be used as constructors i.e. can't be called with
new
- have no
arguments
variable
๐ก just a tip
Arrow functions fit very nicely as callbacks.
const randomNumbers = [1, 12, 30]; let randomNumbersDoubled = []; setTimeout(() => { console.log("Doubling the array now..."); randomNumbersDoubled = randomNumbers.map((number) => (number * 2)); console.log(randomNumbersDoubled); }, 500);
With arrow functions, at least initially, it is mostly the syntax that you have to get used to. I've prepared an Arrow Functions Cheat Sheet which has all the cases discussed in this article.
๐๐ป Get your FREE copy of the cheat sheet: click here
๐๐ป Follow me on twitter: click here
๐๐ป Subscribe to my newsletter