loading...

5 Tips for writing better conditionals in JavaScript

antonioerdeljac profile image Antonio Erdeljac ・3 min read

Conditionals are one of the first things we learn as developers. They are easy to understand and are easy to grasp from a mathematical standpoint. Due to their non-complex nature, developers often stop learning new practices regarding conditionals, assuming they know everything there is to know about them.

In this blog post, we are going to craft different ways of using conditionals in our code, focused on readability.

These tips are commonly mentioned in other articles, but I wanted to curate my own experience as a JavaScript developer.

1. Use object literals instead of switch

Let's take a look at a common switch conditional example:

switch (name) {
  case 'antonio':
    return { name: 'antonio' };
  case 'matthew':
    return { name: 'matthew' };
  case 'linus':
    return { name: 'linus' };
  default:
    return undefined;
}
Enter fullscreen mode Exit fullscreen mode

Is there anything wrong with this code? No. This code will work just fine, and it is a common practice. But why not go a step further and apply a cleaner syntax using object literal?

const userFactory = {
  antonio: { name: 'antonio' },
  matthew: { name: 'matthew' },
  linus: { name: 'linus' },
};

const name = 'antonio';
return userFactory[name]; // { name: 'antonio' }
Enter fullscreen mode Exit fullscreen mode

What we've achieved here is cleaner syntax, higher readability, and easier modularity for future modifications.

You could improve this even further utilizing Lodash's get functionality, to ensure safe fallbacks.

import { get } from 'lodash';

const userFactory = {
  antonio: { name: 'antonio' },
  matthew: { name: 'matthew' },
  linus: { name: 'linus' },
};

const name = 'antonio';
return get(userFactory, name, { name: 'fallback' });
Enter fullscreen mode Exit fullscreen mode

Does this mean you should completely eliminate switch statements? No. This is just an example of an alternative, sometimes what works best is what you or your team understand best. An example where I would heavily use object literals is in a reducer, since it essentially is a giant switch statement, why not make it more readable?

2. Use Array.includes instead of multiple conditions

Another common example of conditionals is the following:

if (name === 'antonio' || name === 'matthew' || name === 'linus') {
  return true;
}
Enter fullscreen mode Exit fullscreen mode

Again, there is nothing fundamentally wrong with this code, but let's make it prettier.

const admins = ['antonio', 'matthew', 'linus'];

if (admins.includes(name)) {
  return true;
}
Enter fullscreen mode Exit fullscreen mode

See the difference? Notice how easier it is to add new admins when we've separated concerns?

3. Use default function parameters

This one is not so much of a eureka discovery, but it can be useful to someone who is not yet utilizing it.

We often write examples like this in our functions:

function (name) {
  let finalName = name;

  if (name === undefined) {
    finalName = 'antonio'
  }

  // do some logic with finalName
}
Enter fullscreen mode Exit fullscreen mode

How can we make this prettier? Using default parameter values.

function (name = 'antonio') {
  // do some logic with name
}
Enter fullscreen mode Exit fullscreen mode

4. Using Array.every & Array.some

Let's say you're writing a function that runs our items through conditional and requires all of the items to pass.

We might wanna write something like this:

const users = [
  { name: 'Antonio', isAdmin: true },
  { name: 'Matthew', isAdmin: true },
  { name: 'Linus', isAdmin: true },
];

let areAllAdmins;

users.forEach((user) => {
  if (!areAllAdmins) { // break function };

  areAllAdmins = user.isAdmin === true;
});
Enter fullscreen mode Exit fullscreen mode

Instead, we can shorten this:

const users = [
  { name: 'Antonio', isAdmin: true },
  { name: 'Matthew', isAdmin: true },
  { name: 'Linus', isAdmin: true },
];

const areAllAdmins = users.every((user) => !!user.isAdmin);
Enter fullscreen mode Exit fullscreen mode

Or, alternatively using Array.some:

const users = [
  { name: 'Antonio', isAdmin: true },
  { name: 'Matthew', isAdmin: true },
  { name: 'Linus', isAdmin: true },
];

const areAllAdmins = users.some((user) => !!user.isAdmin);
Enter fullscreen mode Exit fullscreen mode

5. Returning early

Instead of returning a single variable at the end of our function, we can utilize early returns in order to simplify our code.

function canAccess(user) {
  let finalStatus;

  if (user) {
    if (user.isAdmin) {
      finalStatus = true;
    } else {
      finalStatus = false;
    }
  }

  return finalStatus;
}
Enter fullscreen mode Exit fullscreen mode

Now let's utilize early returns:

function canAccess(user) {
  if (!user) return false;
  if (user.isAdmin) return true;
  if (!user.isAdmin) return false;
}
Enter fullscreen mode Exit fullscreen mode

Of course, this can be even more simplified with return user.isAdmin, but for the sake of tutorial, I am writing explicitly.

Conclusion

These have been some of my tips for better handling of conditionals.

Being a developer is a never-ending tutorial, never assume you know everything about a subject and be eager to always learn new things. Even the simplest things can be improved, either in optimization, or readability.

Discussion

pic
Editor guide