Me

Avoid Else, Return Early

tldr;


Programmers are often taught to have a ‘single exit point’ in their methods, i.e. only return from a single location.


function () {
  var result;

  if () {
    result = x
  } else {
    if () {
      result = y
    } else {
      result = z
    }
  }

  return result // this return is single and lonely
}

This is a poor guideline in my opinion:

Example if/else refactoring

Consider this typical node callback code:


function(err, results) {
  if (!err) {
    doOtherStuff()
    doMoreStuff()
    // ... etc
    // ... etc
  } else {
    handleError(err)
  }
}

There’s a few problems here. First, our error handling is dangling off the end of the method. If the “happy path” is many lines long, it can easily become unclear what the else even refers to.

Let’s try keep the “meat” of the code at the bottom of the method, and keep any special cases together at the top:


function(err, results) {
  if (err) {
    handleError(err)
  } else {
    doOtherStuff()
    doMoreStuff()
    // ... etc
    // ... etc
  
  }
}

It’s very easy to get unweildy levels of indentation in JavaScript, so we should strive to reduce any unnecessary nesting.

In this case, we can remove the else indentation around our “happy path” by replacing the else with a return:


function(err, results) {
  if (err) {
    handleError(err)
    return
  }

  doOtherStuff()
  doMoreStuff()
  // ... etc
  // ... etc
}

Not only does this unindent a bunch of code, it also moves the method’s main purpose/intention/meat to indentation level 0.

We often don’t care about return values in non-promise-based async JS, so we can futher compact the method vertically by putting the return first, removing a whole line and more braces:


function(err, results) {
  if (err) return handleError(err)

  doOtherStuff()
  doMoreStuff()
  // ... etc
  // ... etc
}

2018 edit: To more clearly signal that the return value is unimportant you can use the void operator:


function(err, results) {
  if (err) return void handleError(err)
  // ...
}

It also obeys the “one logical statement per line” guideline, compacting the error detection and handling noise to a single line.

Another benefit is that the return keyword is generally syntax highlighted, so all exit points become very clear, as opposed to hidden inside result = something assignments.

This final form has:

Rebecca Murphey has also written about this

The end.


2018 edit: As with any programming practice, one shouldn’t see this as a hard rule that must be obeyed at all times. Early returns make little difference for small functions, and may even increase the cognitive load. However, I find the logic-flattening benefits of early returns become increasingly compelling as the size and complexity of a function increases.

Lots of discussion about this post:

  1. darknets reblogged this from toxley-blog and added:
    /me shall be writing way more code like this!! It always seems like I’m indenting the crap out of things this is a nice...
  2. vagorage-blog reblogged this from toxley-blog
  3. toxley-blog posted this
blog comments powered by Disqus