JavaScript Switch Statements
JavaScript switch statements are useful when one value can match several discrete cases. They are not a cleaner form of every if...else chain. A good switch makes a set of exact options easier to scan. A bad switch hides range checks, mixed conditions, and missing break bugs in a little ceremony costume.
Use switch when the shape is "this one value equals which case?"
The problem switch solves
This works:
function getRoleLabel(role) {
if (role === "admin") {
return "Administrator";
} else if (role === "editor") {
return "Editor";
} else if (role === "viewer") {
return "Viewer";
}
return "Unknown role";
}
But every condition compares the same value. A switch makes that structure explicit:
function getRoleLabel(role) {
switch (role) {
case "admin":
return "Administrator";
case "editor":
return "Editor";
case "viewer":
return "Viewer";
default:
return "Unknown role";
}
}
Because each case returns, no break is needed. The function exits immediately.
Basic syntax
switch (value) {
case firstMatch:
// run this
break;
case secondMatch:
// run this
break;
default:
// run this if nothing matched
}
The switch expression is evaluated once. Each case is compared with strict equality, the same comparison used by ===.
const value = "1";
switch (value) {
case 1:
console.log("number");
break;
case "1":
console.log("string");
break;
}
// "string"
There is no automatic type conversion.
break prevents fall-through
If a matching case does not end with break, return, or throw, execution continues into the next case.
const access = "admin";
switch (access) {
case "admin":
console.log("Can manage users");
case "editor":
console.log("Can edit content");
break;
default:
console.log("Can read content");
}
// "Can manage users"
// "Can edit content"
That behavior is called fall-through. It is built into switch. Sometimes it is useful. Often it is an accidental bug wearing a hat.
Intentional fall-through
Fall-through can group cases that share behavior:
function getFileType(extension) {
switch (extension) {
case "jpg":
case "jpeg":
case "png":
case "webp":
return "image";
case "mp4":
case "mov":
return "video";
default:
return "unknown";
}
}
Here the empty cases are intentional. Several extensions map to the same return value.
If you intentionally fall through from a non-empty case, leave a comment:
switch (status) {
case "new":
notifyOwner();
// Falls through to mark the item active.
case "active":
markVisible();
break;
}
The comment tells the next reader that the missing break is not an accident.
default handles no match
default runs when no case matches:
function getStatusMessage(status) {
switch (status) {
case 200:
return "OK";
case 404:
return "Not found";
case 500:
return "Server error";
default:
return "Unknown status";
}
}
You can place default anywhere, but putting it last is usually easiest to read.
Cases do not create block scope
This surprises people:
switch (role) {
case "admin":
const label = "Administrator";
return label;
case "editor":
const label = "Editor";
return label;
}
That can throw a syntax error because both label declarations live in the same switch block. Wrap each case body in braces when you need local declarations:
switch (role) {
case "admin": {
const label = "Administrator";
return label;
}
case "editor": {
const label = "Editor";
return label;
}
default:
return "Unknown role";
}
The braces create the block scope the cases do not create by themselves.
Do not force ranges into switch
This is a poor fit:
const score = 87;
switch (score) {
case score >= 90:
console.log("A");
break;
case score >= 80:
console.log("B");
break;
}
The switch value is 87. The case expressions evaluate to booleans. 87 === true is false, so nothing works the way you hoped.
You may see this pattern:
switch (true) {
case score >= 90:
return "A";
case score >= 80:
return "B";
default:
return "C";
}
It works, but an if...else chain is clearer:
if (score >= 90) return "A";
if (score >= 80) return "B";
return "C";
Use the construct that matches the logic, not the one you are trying to practice.
When switch is a good choice
Use switch when:
- One value is compared against several exact options.
- Cases are enum-like strings or numbers.
- Each case has a distinct return value or action.
- Grouping several cases under the same behavior improves readability.
Examples include roles, status codes, command names, keyboard keys, and simple state-machine transitions.
Key Takeaways
switchcompares one expression against cases using strict equality.- Missing
break,return, orthrowcauses fall-through. - Fall-through is useful for grouping cases, but accidental fall-through is a common bug.
- Cases do not create their own block scope; use braces when declaring
letorconst. - Use
ifstatements for ranges and mixed conditions. Useswitchfor exact choices.