switch in JavaScript: branching on the value of an expression

switch compares a value against a list of cases and runs the first one that matches. The comparison is strict and execution carries on until a break.
3 min read
Believemy logo

When one value has to be compared against five or six possibilities, the chain of else if becomes tiring to read: the variable name is repeated on every line, and the reader has to confirm each time that it really is the same one.

switch answers that precise case. It announces the value once at the top, then lists the cases flat.


Definition

switch evaluates the expression in parentheses, compares it against each case in order, and runs the block of the first one that matches. The default branch covers whatever no case anticipated.

JAVASCRIPT
function label(status) {
  switch (status) {
    case "paid":
      return "Paid";
    case "pending":
      return "Pending";
    default:
      return "Unknown status";
  }
}

console.log(label("pending"));   // "Pending"

Here every case ends with a return, which leaves the function. Without one, a break would be needed, and its absence is the main trap of this structure.


Without break, execution carries on

A case is not a closed block, it is an entry point. Once a case matches, the engine runs everything that follows, the later cases included, until it meets a break or the end of the switch.

JAVASCRIPT
const day = "sunday";

switch (day) {
  case "saturday":
  case "sunday":
    console.log("Weekend");    // both cases share this block
    break;
  default:
    console.log("Working day");
}

This behavior helps when several values share the same treatment, as above. It turns into a bug the moment a break is forgotten: two branches run one after the other, without the slightest warning.


The comparison is strict

Matching the expression against each case uses Strict equality (===). The type therefore counts as much as the value, which catches people out when the data comes from a form or a URL, where everything arrives as a string.

JAVASCRIPT
switch ("1") {
  case 1:
    console.log("number");
    break;
  default:
    console.log("no match");   // this is the branch taken
}
Good to know

Declaring a variable with let or const inside a case requires wrapping that case in braces. Without them, every case shares a single block, and two declarations of the same name stop the file from loading.


Frequently asked questions

Question

Should a default always be written?

It is strongly advised. Without a default, an unexpected value crosses the switch without anything happening, and the program carries on with missing data. A branch that logs the unexpected case, or raises an error, turns a silence into usable information.


Question

When is a lookup object the better choice?

As soon as each case merely maps one value to another. An Object whose keys are the cases reads in one line, tests easily and changes with no risk of forgetting a break. The switch takes the lead again when the branches do something other than hand back a value.

JAVASCRIPT
const LABELS = { paid: "Paid", pending: "Pending" };
const label = (status) => LABELS[status] ?? "Unknown status";

console.log(label("paid"), label("void"));   // Paid Unknown status


Question

Can switch test ranges?

Not directly, since each case compares an exact value. The workaround is writing switch (true) and putting the comparisons in the cases, but it hides the intent more than it serves it. For ranges, a chain of if and else remains the most readable form.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.