Complete guide to the switch statement in JavaScript. Learn switch-case syntax, fall-through behavior, break usage, default clause, and when to choose switch over if-else with practical examples.
The switch statement provides a clean way to execute different code blocks based on the value of a single expression. It's an alternative to long if-else if chains when you're comparing one variable against multiple possible values.
What is a Switch Statement?
A switch statement evaluates an expression and matches its value against multiple case labels. When a match is found, the corresponding code block executes. If no match is found, the optional default block runs.
┌─────────────────────────────┐
│ Evaluate Expression │
└─────────────┬───────────────┘
│
┌─────────┼──────────────────────────┐
│ │ │ │
▼ ▼ ▼ ▼
┌────────┐┌────────┐┌────────┐ ┌──────────┐
│ Case 1 ││ Case 2 ││ Case 3 │... │ Default │
│ Match? ││ Match? ││ Match? │ │ (no match│
└───┬────┘└───┬────┘└───┬────┘ └────┬─────┘
│ │ │ │
▼ ▼ ▼ ▼
[Block 1] [Block 2] [Block 3] [Default Block]
│ │ │ │
└─────────┴─────────┴───────────────┘
│
▼
Continue Program
Syntax
switch (expression) {
case value1:
// code block 1
break;
case value2:
// code block 2
break;
case value3:
// code block 3
break;
default:
// code block if no case matches
}
How Switch Works — Step by Step
- The
expression is evaluated once. - The result is compared with each
case value using strict equality (===). - If a match is found, the code after that
case executes. - The
break statement exits the switch block. - If no match is found, the
default block executes (if present).
Basic Examples
Example 1: Day of the Week
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;
case 6:
console.log("Saturday");
break;
case 7:
console.log("Sunday");
break;
default:
console.log("Invalid day number");
}
Example 2: Fruit Color
let fruit = "banana";
switch (fruit) {
case "apple":
console.log("Apple is red or green.");
break;
case "banana":
console.log("Banana is yellow.");
break;
case "grape":
console.log("Grape is purple.");
break;
default:
console.log("Unknown fruit.");
}
The Break Statement
The break statement is critical in switch. Without it, execution "falls through" to the next case.
Without Break (Fall-Through Behavior)
let num = 2;
switch (num) {
case 1:
console.log("One");
case 2:
console.log("Two");
case 3:
console.log("Three");
case 4:
console.log("Four");
default:
console.log("Default");
}
All cases after the match execute because there's no break!
With Break (Correct Behavior)
let num = 2;
switch (num) {
case 1:
console.log("One");
break;
case 2:
console.log("Two");
break;
case 3:
console.log("Three");
break;
default:
console.log("Default");
}
Intentional Fall-Through (Grouped Cases)
Sometimes fall-through is intentional — to group multiple cases that share the same code:
let day = "Saturday";
switch (day) {
case "Monday":
case "Tuesday":
case "Wednesday":
case "Thursday":
case "Friday":
console.log("It's a weekday. Time to work!");
break;
case "Saturday":
case "Sunday":
console.log("It's the weekend. Time to relax!");
break;
default:
console.log("Invalid day.");
}
It's the weekend. Time to relax!
Grouped Cases with Different Actions
let month = 4;
let season;
switch (month) {
case 12:
case 1:
case 2:
season = "Winter";
break;
case 3:
case 4:
case 5:
season = "Spring";
break;
case 6:
case 7:
case 8:
season = "Summer";
break;
case 9:
case 10:
case 11:
season = "Autumn";
break;
default:
season = "Invalid month";
}
console.log("Month " + month + " is in " + season);
The Default Clause
The default clause handles cases when no case matches. It can be placed anywhere in the switch, but convention places it last.
let color = "purple";
switch (color) {
case "red":
console.log("Stop!");
break;
case "yellow":
console.log("Caution!");
break;
case "green":
console.log("Go!");
break;
default:
console.log("Unknown traffic signal color: " + color);
}
Unknown traffic signal color: purple
Switch Uses Strict Equality (===)
Switch comparisons use strict equality — no type coercion occurs:
let value = "1";
switch (value) {
case 1:
console.log("Number 1");
break;
case "1":
console.log("String '1'");
break;
default:
console.log("No match");
}
Switch with Expressions
The switch expression can be any valid JavaScript expression:
let score = 85;
switch (true) {
case score >= 90:
console.log("Grade A");
break;
case score >= 80:
console.log("Grade B");
break;
case score >= 70:
console.log("Grade C");
break;
case score >= 60:
console.log("Grade D");
break;
default:
console.log("Grade F");
}
This pattern uses switch(true) to evaluate boolean expressions in cases, similar to if-else chains.
Practical Programs
Program 1: Simple Calculator
let a = 10, b = 5;
let operator = "*";
switch (operator) {
case "+":
console.log(`${a} + ${b} = ${a + b}`);
break;
case "-":
console.log(`${a} - ${b} = ${a - b}`);
break;
case "*":
console.log(`${a} * ${b} = ${a * b}`);
break;
case "/":
if (b !== 0) {
console.log(`${a} / ${b} = ${a / b}`);
} else {
console.log("Error: Division by zero");
}
break;
case "%":
console.log(`${a} % ${b} = ${a % b}`);
break;
default:
console.log("Invalid operator: " + operator);
}
Program 2: Month Days Counter
let month = 2;
let year = 2024;
let days;
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
days = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0 ? 29 : 28;
break;
default:
days = -1;
}
if (days > 0) {
console.log(`Month ${month} of ${year} has ${days} days.`);
} else {
console.log("Invalid month!");
}
Month 2 of 2024 has 29 days.
Program 3: HTTP Status Code Handler
let statusCode = 404;
switch (statusCode) {
case 200:
console.log("OK - Request successful");
break;
case 201:
console.log("Created - Resource created successfully");
break;
case 301:
console.log("Moved Permanently - Resource relocated");
break;
case 400:
console.log("Bad Request - Invalid syntax");
break;
case 401:
console.log("Unauthorized - Authentication required");
break;
case 403:
console.log("Forbidden - Access denied");
break;
case 404:
console.log("Not Found - Resource doesn't exist");
break;
case 500:
console.log("Internal Server Error");
break;
default:
console.log("Unknown status code: " + statusCode);
}
Not Found - Resource doesn't exist
Program 4: Role-Based Access
let userRole = "editor";
switch (userRole) {
case "admin":
console.log("Access: Full system control");
console.log("Can: Create, Read, Update, Delete users");
break;
case "editor":
console.log("Access: Content management");
console.log("Can: Create, Read, Update content");
break;
case "viewer":
console.log("Access: Read only");
console.log("Can: View content");
break;
case "guest":
console.log("Access: Limited");
console.log("Can: View public content only");
break;
default:
console.log("Access: Denied - Unknown role");
}
Access: Content management
Can: Create, Read, Update content
Program 5: Direction Commands
let command = "north";
let x = 0, y = 0;
switch (command.toLowerCase()) {
case "north":
case "up":
y++;
console.log("Moving north...");
break;
case "south":
case "down":
y--;
console.log("Moving south...");
break;
case "east":
case "right":
x++;
console.log("Moving east...");
break;
case "west":
case "left":
x--;
console.log("Moving west...");
break;
default:
console.log("Unknown command!");
}
console.log(`Position: (${x}, ${y})`);
Moving north...
Position: (0, 1)
Switch vs If-Else: When to Use Which
| Feature | Switch | If-Else |
|---|
| Best for | Comparing ONE variable to many values | Complex conditions, ranges |
| Comparison type | Strict equality only (===) | Any comparison operator |
| Readability | Better for 4+ equality checks | Better for 2-3 conditions |
| Range checks | Not directly supported | Natural fit |
| Multiple variables | Not ideal | Works well |
| Performance | Potentially faster (jump table) | Sequential evaluation |
// ✅ Use switch: one variable, many exact values
switch (status) {
case "pending": /* ... */ break;
case "active": /* ... */ break;
case "closed": /* ... */ break;
}
// ✅ Use if-else: ranges and complex conditions
if (score >= 90) { /* ... */ }
else if (score >= 80 && attendance > 75) { /* ... */ }
else { /* ... */ }
Common Mistakes
Mistake 1: Forgetting Break
let fruit = "apple";
// ❌ Missing breaks causes fall-through
switch (fruit) {
case "apple":
console.log("Apple");
case "banana":
console.log("Banana");
case "cherry":
console.log("Cherry");
}
Mistake 2: Using Loose Equality Expectations
let input = "2"; // string
// ❌ This won't match because switch uses ===
switch (input) {
case 2:
console.log("Matched number 2");
break;
default:
console.log("No match - types differ!");
}
Mistake 3: Declaring Variables Without Block Scope
let action = "create";
// ❌ Variable declarations in cases share scope
// switch (action) {
// case "create":
// let message = "Created"; // SyntaxError if 'let' in another case too
// break;
// case "delete":
// let message = "Deleted"; // Duplicate declaration!
// break;
// }
// ✅ Use blocks {} for each case
switch (action) {
case "create": {
let message = "Created";
console.log(message);
break;
}
case "delete": {
let message = "Deleted";
console.log(message);
break;
}
}
Best Practices
- Always include
break unless fall-through is intentional (and documented). - Always include
default to handle unexpected values. - Use block scoping
{} in cases when declaring variables. - Comment intentional fall-throughs for clarity.
- Consider object lookup for simple value mapping instead of switch.
- Keep switch cases focused — extract complex logic into functions.
// Object lookup alternative to switch
const dayNames = {
1: "Monday",
2: "Tuesday",
3: "Wednesday",
4: "Thursday",
5: "Friday",
6: "Saturday",
7: "Sunday"
};
let dayNum = 5;
console.log(dayNames[dayNum] || "Invalid day");
Interview Questions
Q1: What comparison does switch use — == or ===?
Answer: Switch uses strict equality (===). There is no type coercion. case "1" will NOT match the number 1.
Q2: What happens if you omit the break statement?
Answer: Without break, execution "falls through" to the next case regardless of whether it matches. All subsequent cases execute until a break or the end of the switch block is reached.
Q3: Can the default case be placed anywhere in a switch?
Answer: Yes, default can be placed anywhere. However, if placed before other cases without a break, fall-through applies. Convention places it last.
Q4: Can you use expressions in case labels?
Answer: Case labels must be constant expressions evaluated at compile time. However, you can use switch(true) and put expressions in case labels: case (x > 5):.
Answer: For many cases with equality checks, some engines can optimize switch into a jump table (O(1) lookup) vs sequential if-else checks (O(n)). In practice, the difference is negligible for small numbers of cases.
Q6: Can you use switch with strings?
Answer: Yes, switch works with any type including strings, numbers, booleans. Comparison is always strict equality.
Q7: What is the scope of variables declared inside a switch?
Answer: Variables declared with var are function-scoped. Variables with let/const are block-scoped to the entire switch (not individual cases), which can cause issues. Use {} blocks in cases to create separate scopes.
Q8: When should you use switch(true)?
Answer: switch(true) is useful when you need range comparisons or complex conditions but prefer switch syntax. Each case contains a boolean expression, and the first truthy one executes.
Q9: Can switch handle multiple values for one action without fall-through?
Answer: Grouped cases (stacking case labels without code between them) is the idiomatic way: case "a": case "b": case "c": /* action */ break;
Q10: What are modern alternatives to switch?
Answer: (1) Object/Map lookup for value mapping, (2) Array methods like find() for condition matching, (3) Strategy pattern for complex behaviors, (4) Optional chaining with nullish coalescing for simple defaults.
Q11: Can you use return inside a switch within a function?
Answer: Yes, return exits the function and implicitly exits the switch, making break unnecessary when returning values.
Q12: How do you handle TypeScript's exhaustive checking with switch?
Answer: TypeScript can verify all enum/union cases are handled. Assign the variable to never type in default: if a case is missing, TypeScript shows a compile error. This ensures type safety.