How to properly use `if` statements

Writing Clean JavaScript

What's the Problem?

When running a function with lots of conditions, I often see complex nested if blocks popping up, and sometimes they can be extremely difficult to follow. Below may be easy enough for right now, but it's setting the foundation for functionality we expect to grow.

const order = function(customOrder) {
    if (customOrder.pizza && customOrder.toppings) {
      if (customOrder.pizza === 'redsauce') {
        if (customOrder.vegetarian) {
          var toppings = [
            'olives',
            'peppers',
            'tomatoes'
          ];
        } else if (customOrder.meatLovers) {
          var toppings = [
            'sausage',
            'bacon',
            'ham',
          ];
        } else if (customOrder.everything) {
          var toppings = [
            'olives',
            'peppers',
            'tomatoes',
            'sausage',
            'bacon',
            'ham',
          ];
        }
        return toppings;
      }
    }
    return [];
};

What Can You Do?

With just a few intentional habits, you can write code that's scalable the first time you write it, instead of merely accepting the inevitability of tech debt and eventual refactoring.

Rule #1 : use early returns instead of wrapping your code in an if  block. If the whole function is inside one big block, then you can easily avoid one indent level like this.

const order = function(customOrder) {
    if (!customOrder.pizza || !customOrder.toppings) return [];
    if (customOrder.pizza !== 'redsauce') return [];
    // other scripts
};

Rule #2 : consolidate conditions into variables/constants, and use fewer if statements if possible.

const order = function(customOrder) {
    const hasToppingOptions = customOrder.pizza
      && customOrder.toppings
      && customOrder.pizza === 'redsauce';
    if (!hasToppingOptions) return [];
    // other scripts
};

Now, when you read the expression in plain English, it's suddenly very clear what this code is supposed to do, and it lets us be more concise.

Rule #3 : Do not use if blocks to assign values. Even though the variable toppings is not being reassigned here, it's being optionally defined in multiple locations, which is just as confusing. We're better off defining a couple different arrays and optionally concatenating them.

const vegToppings = [
  'olives',
  'peppers',
  'tomatoes'
];
const meatToppings = [
  'sausage',
  'bacon',
  'ham'
];
if (customOrder.vegToppings) return vegToppings;
if (customOrder.meatLovers) return meatToppings;
return vegToppings.concat(meatToppings);

There's a few different ways you could write this, this is just my own preferred method. The point isn't to take this exact approach, but just to look for ways that you can avoid defining a variable in more than one place. Using if blocks in this situation leads to less readable code, more bug-prone code, and code that is difficult to troubleshoot should a bug arise.

When all is said and done, the function we started with now looks like this:

const order = function(customOrder) {
    const hasToppingOptions = customOrder.pizza
      && customOrder.toppings
      && customOrder.pizza === 'redsauce';
    if (!hasToppingOptions) return [];
    const vegToppings = [
      'olives',
      'peppers',
      'tomatoes'
    ];
    const meatToppings = [
      'sausage',
      'bacon',
      'ham'
    ];
    if (customOrder.vegToppings) return vegToppings;
    if (customOrder.meatLovers) return meatToppings;
    return vegToppings.concat(meatToppings);
};

Notice how we had 5 if conditions previously, and now we ended up with only 3, and none are even wrapping a block of code. A function with fewer indent levels is a function that is much easier and straightforward to read and understand.

So are if blocks bad ? Not always, but their usage should be much less passive. What I mean by that is some people write them so frequently that they're just second nature, and that's when they become dangerous. They should never be used just because a dev was on auto-pilot. Make the above habits your new auto-pilot, and use if blocks only when they require active thought.

I know that sometimes taking everything in as a newbie can be overwhelming, but these are the kinds of things I wish I knew from the start. Unfortunately, there's a lot of learning material out there that ignores or sometimes encourages bad habits, so beware of the common examples around the internet. Always look at more than one source, especially for the best practices. These posts are my small effort to help the "me" from 10 years ago, so I hope they're helpful to you!