The Switch/Case Statement in JavaScript

Jan 13, 2020

The switch statement evaluates an expression, and executes a block of code based on which case the expression evaluated to.

const hero = 'Batman';
let sidekick;

switch (hero) {
  case 'Batman':
    sidekick = 'Robin';
    break;
  case 'Aquaman':
    sidekick = 'Aqualad';
    break;
  case 'Superman':
    sidekick = 'Jimmy Olsen';
    break;
  default:
    throw new Error('Unknown hero');
}

sidekick; // 'Robin'

Make sure you don't forget the break statement at the end of a block! If you don't put a break statement at the end of a case block, JavaScript will "fall through" to the next case.

const hero = 'Batman';
let sidekick;

switch (hero) {
  case 'Batman':
    sidekick = 'Robin';
    // Unless there's a `break`, JavaScript will execute the next
    // `case` block.
    // break;
  case 'Aquaman':
    sidekick = 'Aqualad';
    break;
  case 'Superman':
    sidekick = 'Jimmy Olsen';
    break;
  default:
    throw new Error('Unknown hero');
}

// JavaScript executed both the 'Batman' and 'Aquaman' blocks,
// so you get the wrong `sidekick`.
sidekick; // 'Aqualad'

There are some benefits to this behavior. You can execute one block for multiple case statements. For example:

const sidekick = 'Nightwing';
let hero;

switch (sidekick) {
  // The 'Robin' and 'Nightwing' cases are "fallthrough" `case`
  // statements. They execute the same code block as the 'Bluebird'
  // case.
  case 'Robin':
  case 'Nightwing':
  case 'Bluebird':
    hero = 'Batman';
    break;
  case 'Aqualad':
  case 'Tempest':
    hero = 'Aquaman';
    break;
  default:
    throw new Error('Unknown sidekick');
}

hero; // 'Batman'

Equality Check

The switch statement evaluates the given expression once, and compares it against each case expression using strict equality. The below if statement is functionally equivalent to the first example:

const hero = 'Batman';
let sidekick;

if (hero === 'Batman') {
  sidekick = 'Robin';
} else if (hero === 'Aquaman') {
  sidekick = 'Aqualad';
} else if (hero === 'Superman') {
  sidekick = 'Jimmy Olsen';
} else {
  throw new Error('Unknown hero');
}

sidekick; // 'Robin'

Because the switch statement uses strict equality, you're responsible for doing type conversions if you want to compare objects, like dates or MongoDB ObjectIds.

const date = new Date('2020/07/04');
let holiday;

const goodFriday = new Date('2020/04/10');
const independenceDay = new Date('2020/07/04');
const christmas = new Date('2020/12/25');

// Strict equality means two dates aren't equal unless they're
// the same object reference.
date === independenceDay; // false

// `date` is an object, so you need to make sure you convert the
// date to a number using `getTime()`. Otherwise none of the
// cases will hit.
switch (date.getTime()) {
  case goodFriday.getTime():
    holiday = 'Good Friday';
    break;
  case independenceDay.getTime():
    holiday = 'Independence Day';
    break;
  case christmas.getTime():
    holiday = 'Christmas';
    break;
}

holiday; // 'Independence Day'

Alternatives

Unless you're using fallthrough case statements, you can use if as a replacement for switch/case. Another alternative is defining an object or map that contains functions to execute based on case:

const hero = 'Batman';
let sidekick;

const obj = {
  'Batman': () => { sidekick = 'Robin'; },
  'Aquaman': () => { sidekick = 'Aqualad'; },
  'Superman': () => { sidekick = 'Jimmy Olsen'; }
};

// Make sure to use `hasOwnProperty()` if you're using an object,
// otherwise 'constructor' would be a valid `hero`.
if (obj.hasOwnProperty(hero)) {
  obj[hero]();
}

sidekick; // 'Robin'

The advantage of using an object conditional is you can build up the object programatically. If your switch statement is getting a little too repetitive, you can instead build up an object conditional with a for loop.

The switch statement comes with a lot of gotchas, like unintentionally falling through to the next case statement. ESLint has a no-fallthrough rule that can help you catch this at the linter level. However, there's rarely a reason to use switch as opposed to if/else if or objects - because switch is less common than if, fewer developers are comfortable with the semantics of switch.


Did you find this tutorial useful? Say thanks by starring our repo on GitHub!

More Fundamentals Tutorials