When you start to write more complex applications with JavaScript, it's inevitable that you'll start dealing with something known as control flow. This is the term used to describe the flow or path that JavaScript takes when executing your code.

The control part of that is the part of the code where we tell JavaScript to either "do this" or "do that" based on some condition. An easy way to think about your conditional logic is that it acts like your code's traffic cop.

Fortunately, in JavaScript, conditional logic is pretty simple. We already looked at some examples of control flow in this tutorial on JavaScript arrays with loops, but there are three other types that are important to understand: if/else statements, switch statements, and ternary operators.

How to use if/else statements in JavaScript

If/else statements in JavaScript are an incredible tool that makes writing conditional logic easy to implement and understand. Let's take a look at a very simple example:

const songs = [
  { artist: 'Queens of the Stone Age', song: 'Kylopsia' },
  { artist: 'Nine Inch Nails', song: 'Gave Up' },
  { artist: 'Be Your Own Pet', song: 'Bunk Trunk Skunk' }
];

songs.forEach(({ artist, song }) => {
  if (song === 'Kylopsia') {
    console.log(`I'm listening to ${artist}!`);
  }

  if (song === 'Gave Up') {
    console.log(`I'm listening to ${artist}!`);
  }

  if (song === 'Bunk Trunk Skunk') {
    console.log(`I'm listening to ${artist}!`);
  }
});

Here, we utilize the JavaScript .forEach() method to loop over an array of songs. For each song in the array, we check to see what the title of the song is. if the current song title matches the current song that we're "looping over" in the array, we log out that we're listening to the artist that wrote that song.

To log out the artist, we utilize JavaScript string interpolation by wrapping our variable artist in ${} and starting and ending the string we pass to console.log() with backticks (this tells JavaScript that we want to use interpolation in the string). To get to the artist and song variables, we rely on JavaScript object destructuring to "pluck off" the values from the object we're currently looping over.

const songs = [
  { artist: 'Queens of the Stone Age', song: 'Kalopsia' },
  { artist: 'Nine Inch Nails', song: 'Gave Up' },
  { artist: 'Be Your Own Pet', song: 'Bunk Trunk Skunk' }
];

songs.forEach(({ artist, song }) => {
  if (song === 'Gave Up') {
    console.log(`I absolutely love ${artist}`);
  } else {
      console.log(`I'm a fan of ${artist}`);
  }
});

JavaScript also gives us the else statement. Pay close attention to the syntax here. We write our normal if statement, but then immediately after the closing curly brace } we added an else {} statement. This literally says "if the current song we're looping is anything other than 'Gave Up', log out I'm a fan of <Artist Name>."

const songs = [
  { artist: 'Queens of the Stone Age', song: 'Kalopsia' },
  { artist: 'Nine Inch Nails', song: 'Gave Up' },
  { artist: 'Be Your Own Pet', song: 'Bunk Trunk Skunk' }
];

songs.forEach(({ artist, song }) => {
  if (song === 'Gave Up') {
    console.log(`I absolutely love ${artist}!`);
  } else if (song === 'Kalopsia') {
    console.log(`I'm a big fan of ${artist}.`);
  } else {
    console.log(`I'm a fan of ${artist}.`);
  }
});

We can also introduce else if statements. This gives us the ability to say "well, if it's not that song, but it is this song, log out 'I'm a big fan of <Artist Name>'. Here, we keep the else statement to say "if the song is anything other than 'Gave Up' or 'Kalopsia', just log out 'I'm a fan of <Artist Name>.'."

It's worth noting: to write code that's easy to understand and debug (if necessary), it's best to avoid heavy usage of else if statements. These can add unnecessary confusion and lead to unexpected bugs.

How to use switch statements in JavaScript

Another form of conditional logic that's important to understand in JavaScript is the switch statement. switch statements allow you to take a value and "switch" between a series of case statements. Similar to if statements, we can provide some (limited) qualification for a case to be a match. Here's what it looks like:

const getBandEvaluation = (artistName) => {
  switch (artistName) {
    case 'Nine Inch Nails':
      return 'This is my favorite band!';
    case 'Queens of the Stone Age':
      return 'This is a band that I really like!';
    case 'Be Your Own Pet':
      return 'This is a band that I listen to on occasion.';
    default:
      return 'Hmm, I don\'t know this band...';
  }
}

console.log(getBandEvaluation('Nine Inch Nails'));
// Logs 'This is my favorite band!'

Here, we've defined a JavaScript function using arrow syntax that takes in an artistName as an argument. Inside of the function, we've defined a switch statement. Pay close attention to the syntax here. We start with the keyword switch, followed by a set of () parentheses containing some value that we want to evaluate artistName.

Next, in-between {} braces, we add a set of case statements. This is where things can get a bit confusing. What we're saying with each of these is "does artistName match this case? If yes, run the following code after the :."

On the surface, these sound very similar to if statements, but they're a bit different. First, what we can evaluate after the case keyword is limited. For example, we can't pass an object as the value we want to evaluate and switch between properties on that object (for example, case song.artist === 'Nine Inch Nails').

Another interesting part is how the case statements are evaluated. switch statements use a concept know as "fall through" which means that the value we're evaluating will literally pass through each case until we either return, use a break; statement in the case block, or hit the default case.

We see the return version of this above. As soon as we match the artistName, we return some string. Let's look at another example with break; statements added in:

const getBandEvaluation = (artistName) => {
  switch (artistName) {
    case 'Nine Inch Nails':
      console.log('This is my favorite band!');
      break;
    case 'Queens of the Stone Age':
      console.log('This is a band that I really like!');
      break;
    case 'Be Your Own Pet':
      console.log('This is a band that I listen to on occasion.');
      break;
    default:
      console.log('Hmm, I don\'t know this band...');
  }
}

getBandEvaluation('Nine Inch Nails');

Instead of logging out the value returned from the matching case statement, here, we move our console.log() statements into each of the different case blocks. Notice, though, that after each console.log() we've added a break; statement. This is saying "if this was the matching case, don't evaluate the other cases below."

If we left this out, the switch statement would keep evaluating or "fall through" all the way to the default (or, the next return or break; statement).

Though it may not look like it, switch statements are a great way to condense if/else if statements. While they're not perfect due to their limitations of what you can evaluate in your case statement, for simple value evaluation, they're a great tool to have on hand.

How to use ternary operators in JavaScript

The final piece of conditional logic that you'll come across frequently in JavaScript is the ternary operator. The ternary operator is used to write a condense if/else statement. These are most commonly used where an if/else statement would be used to decide what should be returned. These are used where it's helpful to have less code (for clarity or due to limitations of usage, like in React's JSX language).

To make their use clear, let's look at something written with a traditional if/else statement first and then refactor that code to use a ternary statement:

const getFormattedArtistName = (artistName, format) => {
  if (format === 'lower-with-dashes') {
    return artistName.replace(/' '/g, '-').toLowerCase();
  } else {
    return artistName.toLowerCase();
  }
}

console.log(getFormattedArtistName('Nine Inch Nails', 'lower-with-dashes'));
// Logs 'nine-inch-nails'

Simple enough. Let's see how it looks with a ternary operator.

const getFormattedArtistName = (artistName, format) => {
  return format === 'lower-with-dashes' ? artistName.replace(/' '/g, '-').toLowerCase() : artistName.toLowerCase();
}

console.log(getFormattedArtistName('Nine Inch Nails'));
// Logs 'nine-inch-nails'

Even simpler! Here, we remove the use of the if () {} syntax in favor of a single line! Here, we introduce ? and : characters to handle the if and else parts. What we're saying is "if format === 'lower-with-dashes' returns true, we want to return the value after the ?. If it return false, we want to return the value after the :.

Cool, right?

With great responsibility...

While some of the above options may seem easier to use than others, remember: with great power comes great responsibility. It's always worth taking the time to ask "is this the best way to write this, or can I use a simpler form of conditional logic to make this work?"

By doing that, you'll inevitably write code that's easy to understand, easy to debug, and far less buggy.