Better Javascript with less nesting and return early when possible

One of the best practices in Javascript is to avoid too much nesting and return the value or error as soon as possible. We will take a look at some examples around this scenario.

Return early in if else statements

There is an article in dev.to that summarises all the articles around this topic. Look at this example with nested if else statements and a single return point:

//Single Exit Point
function foo(bar){
    value = '';
if (bar > 0) {
  value = "YES";
} else if (bar == 0) {
  value = "MAYBE"
} else {
  value = "NO";
}
  return value;
}
// Call the function
foo(10);

The problem with nesting is we have to wait maybe until the last statement to get the value back. Besides there is only one return in the whole function and this is assumed as bad practice.

These are some good images from here to show the case:

This is what happens with only one return statement <

Therefor the sooner we could return a value the earlier we could leave the function call and the better and faster the code is written and executed. Performance wise it is important to write clean and more readable and maintainable code. And this is one of the use cases. Lets improve it a bit:

//Early Returns with if/else
function foo(bar){
if (bar > 0) {
&nbsp; return "YES";
} else if (bar == 0) {
&nbsp; return "MAYBE"
} else {
&nbsp; return "NO";}
}
foo(10);

We return value whenever a check is done. Even better we can remove the else as well:

//Early Returns with if/else
function foo(bar){
if (bar > 0) {
    return "YES";
}
if (bar == 0) {
&nbsp; return "MAYBE";
}
&nbsp; return "NO";
}
foo(10);

Also we clearly know what we return the value and when we should expect it:

This is best practice to return as early as possible

Less nesting to return early

Along with return early we need to make sure that we have less nesting in our code. Take a look at this example:

function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
// condition 1: fruit must has value
  if (fruit) {
    // condition 2: must be red
    if (redFruits.includes(fruit)) {
      console.log('red');
  // condition 3: must be big quantity  if (quantity > 10) {    console.log('big quantity');  }}
} else {
    throw new Error('No fruit!');
  }
}
// test results
test(null); // error: No fruits
test('apple'); // print: red
test('apple', 20); // print: red, big quantity

Basically we have three levels of nesting and one if/else statement. We can return early when the error condition found which helps to leave the function early:

/_ return early when invalid conditions found _/
function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
// condition 1: throw error early
  if (!fruit) throw new Error('No fruit!');
// condition 2: must be red
  if (redFruits.includes(fruit)) {
    console.log('red');
// condition 3: must be big quantity if (quantity > 10) {  console.log('big quantity');}
}
}

Then we will have less nested statements which is great. Practically the aim in the code should be the most possible readability and maintainability which helps in performance and less error prone code. Having less nesting and return early is one of those key things to accomplish this task.

Thank you for reading.

© 2019
Azadeh Faramarzi

This site is created and maintined by Azadeh Faramarzi , A passionate developer, sport and code lover who loves to share and write when she has some time.