Does your JavaScript Arrow Function Use {}? Use an Explicit Return!

JavaScript Tips For Arrow Functions

David Ryan Morphew
5 min readSep 17, 2021

Table of Contents

  1. Why is My Arrow Function Returning Undefined?
  2. Functions with { } Around the Function Body Require Explicit Returns…Even Arrow Functions
  3. When to Use ( ) => { } Instead of ( ) => ( )
  4. Single-Term Parameter and Single-Line Return: Parentheses Optional
  5. Returning to Our returnGoodDogs Function
  6. Conclusion

Why is My Arrow Function Returning Undefined?

The Scenario

You’ve looked at it a bunch of times. The code still looks good to you. When you use console.logand debuggerinside the function body, you’re getting what you’d expect. So, why is your arrow function returning undefined?

You ask yourself:

Don’t arrow functions always return implicitly?

You’re pretty sure you’ve heard that somewhere before.

Recap with Function Declaration

So, a good-ole’-fashion function declaration will have you use an explicit return (using the return key word).

function starWars(jedi){
return jedi;
}

If you pass in jedi to this starWars() function, you’ll get the return of thejedi.

Return Values of Arrow Functions

Does an Arrow function always return implicitly?

Check out the following examples:

const allDogs = [
{name: "Fluffy", good: false},
{name: "Mr. BigglesWorth", good: true},
{name: "Cheddar", good: true},
{name:"Rex", good: true}
];
const returnGoodDogs = (dogs) => {
dogs.filter(dog => dog.good);
}
const dogsThatGoToHeaven = (dogs) => (dogs)returnGoodDogs(allDogs);dogsThatGoToHeaven(allDogs);

What do you think returnGoodDogs(allDogs)will return given the way it is written right here?

What about dogsThatGoToHeaven(allDogs);?

If you’re not sure, try it out in the console or in a repl.it.

returnGoodDogs: ( ) => { }

Notice that the returnGoodDogs function wraps the body of the function in curly braces {}. This function is what I will refer to as the ( ) => { } type.

When you call the function returnGoodDogs(allDogs), you’re going to get a return of undefined.

allDogs array of dogs is defined along with a returnGoodDogs function that should return only dogs whose attribute of “good” has a value of true, but the arrow function lacks an explicit return in this case and will return undefined.

Where did we go wrong? Is it the with the .filtermethod?

Example showing that the filter method is returning the expected array of only good dogs.

That can’t be it. The filter method returns the array we want.

So, what’s the deal?

Functions with { } Around the Function Body Require Explicit Returns…Even Arrow Functions

Right now, our arrow function (returnGoodDogsabove), like a good-ole’-fashion function declaration, requires an explicit return, since…

A function with a body wrapped in { } requires an explicit return.

There are other important differences between a good-ole’-fashion function declarations and creating an arrow function, but note the similarity here in the need of a return key word:

function functionNeedingExplicitReturn(input){
return input;
}
const arrowFunctionNeedingExplicitReturn = (input) => {
return input;
}

So:

If your arrow function body is wrapped in { }, you need to return explicitly.

To fix our returnGoodDogs function, we’ll need to add in that return keyword:

const returnGoodDogs = (dogs) => {
return dogs.filter(dog => dog.good)
}

dogsThatGoToHeaven: ( ) => ( )

Compare this now to the dogsThatGoToHeaven function that wraps the function body in parentheses:

Example showing that arrow functions with the function body wrapped in parentheses implicitly return the code wrapped in the parentheses.
allDogs still go to heaven with an arrow function that has params and the body wrapped in parentheses.

In thedogsThatGoToHeavenfunction: there’s no returnkeyword, and it returns all the dogs. All dogs go to heaven!

The reason is:

If you wrap the function body of your arrow function in ( ), it will implicitly return what is inside the function body.

So, here’s where the implicit return comes in! But there are reasons why you might not always want to do that.

When to Use ( ) => { } Instead of ( ) => ( )

The ( ) => ( ) type of arrow function will implicitly return a single line of code in the function body.

So:

If you have more than one line of code in the function body, you have to use the ( ) => { } type of arrow function.

Suppose you want to console.log some data in the body, or manipulate the data before your final return line:

const moreThanOneLineInBody = (array) => {
console.log("first line");
const newArray = [...array].reverse();
return newArray;
}

You’ll need to use the ( ) => { } type of arrow function. If you try to wrap that multi-line function body with ( ), you’re going to get an error.

Single-Term Parameter and Singe-Line Return: Parentheses Optional

Let’s try removing the parentheses around the parameter and the function body like this:

const dogsThatGoToHeaven = dogs => dogs
Example of an Arrow Function that does not use parentheses around the parameter of function body.
dogsThatGoToHeaven returns allDogs, the original array that is passed in.

The parentheses are optional here. If you have a single parameter, and a one-line return in the function body, you don’t have to wrap either in parentheses. If you wish, you can just imagine the parentheses are still there.

We can also do this with the ( ) => { } type of arrow function when there is one parameter:

const dogsThatGoToHeaven = dogs => {
return dogs
}

Returning to Our returnGoodDogs Function

So, returning to our returnGoodDogs, we can get it to return only the good dogs when we pass in allDogs by adding an explicit return in the ( ) => {} type of function, or by converting it to the ( ) => ( ) type of function.

( ) => { } Type

const returnGoodDogs = (dogs) => {
return dogs.filter(dog => dog.good)
}

( ) => ( ) Type

const returnGoodDogs = (dogs) => (dogs.filter(dog => dog.good))

Dropping Optional Parentheses

Again, you can drop parentheses if there is a single-term parameter or the function body return is a single line:

( ) => { } Type (without Parameter Parentheses)

const returnGoodDogs = dogs => {
return dogs.filter(dog => dog.good)
}

( ) => ( ) Type (without Parameter & Function Body Parentheses)

const returnGoodDogs = dogs => dogs.filter(dog => dog.good)

Conclusion

Using an arrow function does not in itself mean that the function body will be implicitly returned. If the function body is wrapped in {} you will need to use an explicit return.

For single parameters and single-line returns, parentheses are option with arrow functions.

There are cases where it is preferable to use an arrow function with the function body wrapped in {}, such as when you have more than one line of code in the function body that you want to execute.

--

--

David Ryan Morphew

I’m very excited to start a new career in Software Engineering. I love the languages, frameworks, and libraries I’ve already learned / worked with (Ruby, Rails,