Turning a Pre-ES6 Function into an Arrow Function
You could consider functions as a sort of recipe where you store useful instructions to accomplish something you need done in your program, like performing an action or returning a value. By calling your function, you execute the steps included in your recipe, and you can do so every time you call that function without needing to rewrite the recipe again and again.
// function declaration function sayHiStranger() return 'Hi, stranger!' // call the function sayHiStranger()
You can also write the same function as a function expression, like this:
const sayHiStranger = function () return 'Hi, stranger!'
Arrow functions are always expressions. Here’s how you could rewrite the function above using the fat arrow notation:
const sayHiStranger = () => 'Hi, stranger'
The benefits of this include:
- just one line of code
- no curly braces
Let’s go through the various ways you can write arrow functions.
The No Parens Syntax
In the above example, the function has no parameters. In this case, you must add a set of empty parentheses
() before the fat arrow (
=>) symbol. The same holds when you have more than one parameter:
const getNetflixSeries = (seriesName, releaseDate) => `The $seriesName series was released in $releaseDate` // call the function console.log(getNetflixSeries('Bridgerton', '2020') ) // output: The Bridgerton series was released in 2020
With just one parameter, however, you can go ahead and leave out the parentheses (you don’t have to, but you can):
const favoriteSeries = seriesName => seriesName === "Bridgerton" ? "Let's watch it" : "Let's go out" // call the function console.log(favoriteSeries("Bridgerton")) // output: "Let's watch it"
Be careful, though. If, for example, you decide to use a default parameter, you must wrap it inside parentheses:
// with parentheses: correct const bestNetflixSeries = (seriesName = "Bridgerton") => `$seriesName is the best` // outputs: "Bridgerton is the best" console.log(bestNetflixSeries()) // no parentheses: error const bestNetflixSeries = seriesName = "Bridgerton" => `$seriesName is the best` // Uncaught SyntaxError: invalid arrow-function arguments (parentheses around the arrow-function may help)
And just because you can, doesn’t mean you should. Mixed with a little bit of light-hearted, well-meaning sarcasm, Kyle Simpson (of You Don’t Know JS fame) has put his thoughts on omitting parentheses into this flow chart.
When you only have one expression in your function body, you can keep everything on one line, remove the curly braces, and do away with the
return keyword. You’ve just seen how these nifty one-liners work in the examples above. Here’s one more example, just for good measure. The
orderByLikes() function does what it says on the tin: that is, it returns an array of Netflix series objects ordered by the highest number of likes:
// using the JS sort() function to sort the titles in descending order // according to the number of likes (more likes at the top, fewer at the bottom const orderByLikes = netflixSeries.sort( (a, b) => b.likes - a.likes ) // call the function // output:the titles and the n. of likes in descending order console.log(orderByLikes)
This is cool, but keep an eye on your code’s readability — especially when sequencing a bunch of arrow functions using one-liners and the no parentheses syntax, like in this example:
const greeter = greeting => name => `$greeting, $name!`
What’s going on there? Try using the regular function syntax:
function greeter(greeting) return function(name) return `$greeting, $name!`
Now, you can quickly see how the outer function
greeter has a parameter,
greeting, and returns an anonymous function. This inner function in its turn has a parameter called
name and returns a string using the value of both
name. Here’s how you can call the function:
const myGreet = greeter('Good morning') console.log( myGreet('Mary') ) // output: "Good morning, Mary!"
Watch Out for these Implicit Return Gotchas
When your arrow function contains more than one statement, you need to wrap all of them in curly braces and use the
return keyword. In the code below, the function builds an object containing the title and summary of a few Netflix series (Netflix reviews are from the Rotten Tomatoes website) :
const seriesList = netflixSeries.map( series => const container = container.title = series.name container.summary = series.summary // explicit return return container )
The arrow function inside the
.map() function develops over a series of statements, at the end of which it returns an object. This makes using curly braces around the body of the function unavoidable. Also, as you’re using curly braces, an implicit return is not an option. You must use the
If your arrow function returns an object literal using the implicit return, you need to wrap the object inside round parentheses. Not doing so will result in an error, because the JS engine mistakenly parses the object literal’s curly braces as the function’s curly braces. And as you’ve just noticed above, when you use curly braces in an arrow function, you can’t omit the return keyword.
This syntax is demonstrated in the shorter version of the previous code:
// Uncaught SyntaxError: unexpected token: ':' const seriesList = netflixSeries.map(series => title: series.name ); // Works fine const seriesList = netflixSeries.map(series => ( title: series.name ));
You Can’t Name Arrow Functions
Functions that don’t have a name identifier between the
function keyword and the parameter list are called anonymous functions. Here’s what a regular anonymous function expression looks like:
const anonymous = function() return 'You can't identify me!'
Arrow functions are all anonymous functions:
const anonymousArrowFunc = () => 'You can't identify me!'
As of ES6, variables and methods can infer the name of an anonymous function from its syntactic position, using its
name property. This makes it possible to identify the function when inspecting its value or reporting an error.
Check this out using
console.log(anonymousArrowFunc.name) // output: "anonymousArrowFunc"
But be aware that this inferred
name property only exists when the anonymous function is assigned to a variable, as in the examples above. If you use an anonymous function as a callback, for example, you lose this useful feature. This is exemplified in the demo below where the anonymous function inside the
.setInterval() method can’t avail itself of the
let counter = 5 let countDown = setInterval(() => console.log(counter) counter-- if (counter === 0) console.log("I have no name!!") clearInterval(countDown) , 1000)
And that’s not all. This inferred
name property still doesn’t work as a proper identifier that you can use to refer to the function from inside itself — such as for recursion, unbinding events, etc.
The intrinsic anonymity of arrow functions has led Kyle Simpson to express his view on arrow functions as follows:
Since I don’t think anonymous functions are a good idea to use frequently in your programs, I’m not a fan of using the
=>arrow function form. — You Don’t Know JS