Mastering the functions' return statement
Tags: javascript, bestpractices, beginners
Published: 2022-05-28 05:42:19

---
title: Mastering the functions' return statement
published: true
date: 2022-03-02 17:04:28 UTC
tags: javascript,bestpractices,beginner
canonical_url: https://mindsers.blog/post/mastering-return-statement/
---

 ![Mastering the functions' return statement](https://mindsers.blog/content/images/2022/03/instruction-return-js-thumbnail.jpg)

To end a function, JavaScript uses the statement `return`. The `return` statement is very simple. It's one of the first thing you'll learn in a coding course.

But you shouldn't underestimate its capacity to help you write a cleaner and more performing code (and the opposite when you don't master it well enough).

_I am using JavaScript code to illustrate my point in this post, but it also applies to other programming languages._

#### Summary
<button><svg id="Regular" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.25,7.311,12.53,18.03a.749.749,0,0,1-1.06,0L.75,7.311"></path></svg></button>

[How does the](#how-does-the-return%E2%81%A3-statement-work)`return`[⁣ statement work?](#how-does-the-return%E2%81%A3-statement-work)

- [What about functions with no return statement?](#what-about-functions-with-no-return-statement)
- [The return statement is a “blocking” statement](#the-return-statement-is-a-%E2%80%9Cblocking%E2%80%9D-statement)

[A better use of the return statement](#a-better-use-of-the-return-statement)

- [Getting out of the function as soon as possible](#getting-out-of-the-function-as-soon-as-possible)
- [Make the](#make-the-else-statement-more-useful)`else`[statement more useful](#make-the-else-statement-more-useful)

## How does the `return`⁣  statement work?

We use functions to group together statement which go contextually together. It means they serve the same purpose, do the same task.

First rule we're going to try and follow : one function = one responsibility. Never more than one responsibility. It will make your code so much better.

```js
function addOneTo(a) {
    const result = a + 1
    
    return result
}
```

The function `addOneTo(a)` adds 1 to the value contained in the variable `a`. I explain [JavaScript variables](https://mindsers.blog/post/learn-javascript-variables/) in details in a different post, if you're not comfortable with them yet, I highly encourage you to read it.

The return statement allows us to return the result of the addition this way : `return result`.

In other words, **the** `return` statement **lets us clearly indicate to the JavaScript interpreter which value this function will return.** In our example, we use two variables. We don't want to return `a`, only `result`.

### What about functions with no return statement?

Those of you who, like me, had algorithms classes might remember this : a function must always return something. It's a ground rule. JavaScript follows this rule, **functions always return something**. In the case where you don't want to return a value, something else exists. It's called _procedures_.

The problem is: There are no _procedures_ in JavaScript.

To solve this problem, JavaScript allows us to return an “undefined” value. It's not defined. We don't know what the value is, so we can say it's empty.

```js
function prepareObject(obj) {
    obj.connect({
      // ...
    })
    obj.use({
      // ...
    })
    
    return undefined
}
```

This way, you can use functions as you would use procedures, you put together reusable statements that don't return defined results/values.

The function `prepareObject` runs its statements, and at the end we say that the function return an `undefined` value. For us, it means that we return nothing, but the interpreter is happy because you return a value anyway.

If you try running the `prepareObject` function, you'll see that it returns the value `undefined`.

There are a few ways to make the code simpler, though. First, leave the value blank like this :

```js
function prepareObject(obj) {
    obj.connect({
      // ...
    })
    obj.use({
      // ...
    })
    
    return
}
```

Because “nothing” is returned, the JavaScript interpreter understands that you want to return an `undefined` value and does it automatically.

You can also omit the statement altogether, like this :

```js
function prepareObject(obj) {
    obj.connect({
      // ...
    })
    obj.use({
      // ...
    })
}
```

If you're thinking that is a procedure, I understand why, but it's wrong. Try it, run the `prepareObject` function, you'll see that it returns the value `undefined`.

### The return statement is a “blocking” statement

The fact that `return` is a classical statement allows us to put it anywhere in the code of a function.

```js
function doComplicatedStuff(obj) {
    obj.connect({
      // ...
    })
    
    return obj
    
    obj.use({
      // ...
    })
}
```

The previous code is valid. The only thing you have to remember here is that `return` is a “blocking” statement in the scope of the parent function.

Which means that it indicates the stopping of the function in which it is. It's important to understand because it means that **the code is located after a**  **`return` statement will never be executed.**

The code located after a `return` statement is what we call “dead code”.

In fact, the `return` statement literally means : “this function is done running properly, here is the result you can show to the parent context. No need to read further.”.

## A better use of the `return` statement

If you have asked yourself why we would use `return;` instead of omitting the statement, or if you've wondered why we would write code after a `return`, this part of the post is for you.

Once you understand these two ideas, it becomes possible for you to better your use of the `return` statement. **A good use of `return` makes a for a better code readability.**

### Getting out of the function as soon as possible

When we read code, whether it's ours or someone else's, the more data, the harder it is for our brains to understand it. Jumps between execution contexts are part of the data that needs to be considered, and each function is a new execution context.

This being said, we don't want to use less functions because there are more pros than cons (re-usability, code structuration, etc…).

A way to reduce the complexity of the code is to reduce the number of data to consider. The `return` statement can help us do that. Let's see an example.

```js
function byOrder(a, b) {
    let result = null
    
    if (a.order > b.order) {
        result = 1
    }
    
    if (a.order < b.order) {
        result = -1
    }
    
    if (a.order == b.order) {
        result = 0
    }
    
    return result
}
```

This function is used to tell the [JavaScript function `array.sort` how to sort an array](https://mindsers.blog/fr/post/maitriser-les-tableaux-en-javascript-fp/). It's used like this : `array.sort(byOrder)`.

Let's read the function to understand. Let's see what our brain does when we're debugging to illustrate our point. `a.order` equals `10` and `b.order` equals `0`.

1. First, I see that there is a `result` variable initialized with the value `null`, but the value is going to change because we use the `let` statement.  To read more about this step, read [the detailed post on JavaScript variables](https://mindsers.blog/post/learn-javascript-variables/).
2. One condition : if the order of `a` is superior to `b`. It is, in our case, we modify the value of `result` to `1`. 
3. A new condition : if the order of `a` is less than `b`. It's not our case, no need to go into the details of this condition.
4. A new condition : if the order of `a` is equal to `b`. It's not our case here, no need to go into the details of this condition. 
5. We see that the `return` statement wants to return the value of the `result` variable. The function returns `1` because we are in the scope of the first condition.

We had to read (and understand) more code than necessary to make sure we understood what this function does. The points 3 and 4 above aren't necessary, but we still have to execute them in our brain. We also had to remember what happened before these steps to know what to return.

Now let's try to rewrite the code of  `byOrder` so it can be out as soon as possible, thanks to the proprieties of `return`. Then we'll do the same exercise to compare the code complexity.

```js
function byOrder(a, b) {
    if (a.order > b.order) {
        return 1
    }
    
    if (a.order < b.order) {
        return -1
    }
    
    return 0
}
```

This new function does the exact same thing. It has the same signature as the first function. Let's try to read it now (as a reminder, `a.order` equals `10` and `b.order` equals `0`) :

1. First, I enter the function and there is a condition straight away : if the order of `a` is superior to `b`. It is, in our case, so we return the value 1.

This is how the `return` statement is blocking, and it stops executing the function, in our specific case, the rest of the code is “dead”. There's no point in reading it. We don't need to understand the rest of the function to understand what it does in our case.

There are a lot less parameters to take into account for our brain during the reading. It's way less complex. It makes me think about the`guard` with Swift.

And it's true in almost every case. Try to do the exercise for `a.order === b.order`, even if it's the last tested conditions, the second function is less complex.

### Make the `else` statement more useful

Another way to better the code of `byOrder` is to use the keywords `else` and `else...if`.

```js
function byOrder(a, b) {
    let result = null
    
    if (a.order > b.order) {
        result = 1
    } else if (a.order < b.order) {
        result = -1
    } else {
        result = 0
    }
    
    return result
}
```

We're mimicking the behavior of the solution with the `return` because the next conditions aren't executed as soon as a corresponding condition is found.

However, the solution isn't right because I think it's still overloaded, and it requires more focus than the return solution we mentioned above.

Some bypass this problem by using `return`. But they forget the point of using`else`.

```js
function byOrder(a, b) {
    if (a.order > b.order) {
        return 1
    } else if (a.order < b.order) {
        return -1
    } else {
        return 0
    }
}
```

In this specific case, you have to choose : either `else`, or `return`. The use of `return` cancels the pros to use `else` and it complicates the code too. This code has no other purpose than to show that the person who wrote didn't really understand the subtleties of `else` statement and `return` statement. Don't do that.

By using solely the `return` in this function, you delete a few words. But more importantly, you delete a full scope (in the last `else`) and you delete a level of indentation, which, as we saw before, help to make your code clearer and less complex.

Personally, I rarely use `else` anymore in my code because I can, in most cases, write a function that is easier to read and understand by using `return` exclusively.

Don't make me say what I didn't say, `else` and `else...if` statements are very useful structures, I still use them as needed. My point here is that they're only useful in some situation. There's no use using them if there are other keywords or structures that are best fitted for our situation. This advice works for everything in programming.

* * *

In short, the return statement (`return`) allows returning a value, defined or not, to the parent context of the function. When the return statement is run, it stops the execution of the current function.

It helps to optimize our code writing to reduce the number of scopes and different levels of indentation inside a single function. It also helps prevent having too many data to go through when we're debugging.