Switch Statement Syntax
A switch statement evaluates an expression once and compares it against multiple case values using strict equality (===).
let day = 3;
switch (day) {
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
case 4:
console.log("Thursday");
break;
case 5:
console.log("Friday");
break;
default:
console.log("Weekend");
}
break and default
break exits the switch block after a case executes. Without it, execution "falls through" to the next case. default runs when no case matches β it is equivalent to the else in an if/else chain.
let fruit = "grape";
switch (fruit) {
case "apple":
console.log("Apple selected.");
break;
case "banana":
console.log("Banana selected.");
break;
default:
console.log("Unknown fruit: " + fruit);
}
default does not have to be the last case β it can appear anywhere. However, placing it last is the conventional and most readable approach.
Fall-through Behavior
When you omit break, execution continues ("falls through") into the next case block. This is a common source of bugs, but can also be used intentionally.
Accidental Fall-through (Bug)
let color = "red";
switch (color) {
case "red":
console.log("Red light β stop.");
// BUG: forgot break!
case "yellow":
console.log("Yellow light β caution.");
break;
case "green":
console.log("Green light β go.");
break;
}
Intentional Fall-through (Multiple Cases, Same Block)
let month = 4; // April
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log("31 days");
break;
case 4:
case 6:
case 9:
case 11:
console.log("30 days");
break;
case 2:
console.log("28 or 29 days");
break;
}
When you intentionally fall through, add a comment like // falls through to signal to readers (and linters) that the missing break is deliberate.
Switch vs if-else β Comparison
| Feature | switch | if / else if |
|---|---|---|
| Comparison type | Strict equality (===) only | Any expression/condition |
| Range checks | Not suitable | Works (age > 18) |
| Multiple values β same block | Clean with fall-through | Verbose (multiple || conditions) |
| Readability for many values | Very clear | Gets long |
| Variable type checked | Any primitive | Any value |
| Default/else | default: | else |
Switch with Strings
function getStatusMessage(status) {
switch (status) {
case "pending":
return "Your order is being processed.";
case "shipped":
return "Your order is on its way!";
case "delivered":
return "Your order has been delivered.";
case "cancelled":
return "Your order was cancelled.";
default:
return "Unknown status: " + status;
}
}
console.log(getStatusMessage("shipped")); // Your order is on its way!
console.log(getStatusMessage("delivered")); // Your order has been delivered.
console.log(getStatusMessage("refunded")); // Unknown status: refunded
switch(true) Pattern
You can pass true as the switch expression, and then write boolean expressions as cases. This makes switch work like a chain of if/else if statements.
let bmi = 27.5;
switch (true) {
case bmi < 18.5:
console.log("Underweight");
break;
case bmi < 25:
console.log("Normal weight");
break;
case bmi < 30:
console.log("Overweight");
break;
default:
console.log("Obese");
}
Object Lookup β A Modern Alternative
For simple value mappings, an object lookup can replace a switch with a single expression.
// Switch version
function getDayName(num) {
switch (num) {
case 1: return "Monday";
case 2: return "Tuesday";
case 3: return "Wednesday";
case 4: return "Thursday";
case 5: return "Friday";
default: return "Weekend";
}
}
// Object lookup version β same result, less code
const dayNames = {
1: "Monday", 2: "Tuesday", 3: "Wednesday",
4: "Thursday", 5: "Friday"
};
function getDayNameClean(num) {
return dayNames[num] ?? "Weekend";
}
console.log(getDayNameClean(3)); // Wednesday
console.log(getDayNameClean(7)); // Weekend
Limitations of Switch
- Can only use strict equality β no range or regex checks (unless using
switch(true)). - Fall-through is a common source of bugs.
- Cannot use
let/constacross cases without wrapping in a block{}. - Verbose for simple value-to-value mappings (object lookup is cleaner).
// Lexical declarations in switch cases need a block
let action = "add";
switch (action) {
case "add": {
const result = 1 + 2; // Block scope β OK
console.log("Add: " + result);
break;
}
case "multiply": {
const result = 2 * 3; // Same name β OK because separate block
console.log("Multiply: " + result);
break;
}
}
ποΈ Practical Exercise
Write a function getSeasonInfo(month) using a switch statement that returns an object { season, emoji, months }:
- Dec, Jan, Feb β Winter βοΈ
- Mar, Apr, May β Spring πΈ
- Jun, Jul, Aug β Summer βοΈ
- Sep, Oct, Nov β Autumn π
Use intentional fall-through to group months that share a season.
π₯ Challenge Exercise
Build a simple calculator function calculate(a, operator, b) using switch that handles +, -, *, /, and %. Guard against division by zero. Then refactor it to use an object lookup of functions instead of switch.
π Summary
switchcompares one expression against many cases using strict equality.- Always include
breakunless fall-through is intentional. defaulthandles the unmatched case (likeelse).- Group multiple cases to share one block β a clean use of fall-through.
switch(true)lets you use boolean expressions as cases.- Object lookup tables are often cleaner than switch for simple mappings.
Interview Questions
- What happens if you forget a
breakin a switch case? - Does switch use
==or===for comparison? - When would you prefer switch over if/else if?
- Explain the
switch(true)pattern with a use case. - What is an object lookup table and when is it better than switch?
Frequently Asked Questions
No, because objects and arrays use reference equality. Two separate [] or {} are never strictly equal even if they have the same contents. Primitives (strings, numbers, booleans) work well with switch.
Modern JavaScript engines optimize both similarly. For a very large number of cases (50+), a switch or object lookup may be slightly faster because the engine can build a jump table. For typical applications, the difference is negligible β optimize for readability.
Yes, default can appear anywhere in a switch. If placed first and no specific case matches, execution falls through to default (unless there's a break). Conventionally it belongs last for clarity.