The switch
operator performs strict comparison (===
) between the expression and values in case
. Does not convert types and uses fall-through mechanism:
const value = "5";
switch (value) {
case 5: // false ("5" !== 5)
console.log("Number");
break;
case "5": // true ("5" === "5")
console.log("String");
break;
default:
console.log("Other");
}
// Output: "String"
Key features: Strict comparison, mandatory break
, execution until the first break
.
switch (expression) {
case value1:
// code for value1
break;
case value2:
// code for value2
break;
default:
// default code
}
const userInput = "1";
switch (userInput) {
case 1: // false ("1" !== 1)
console.log("Number one");
break;
case "1": // true ("1" === "1")
console.log("String one");
break;
case true: // false ("1" !== true)
console.log("Boolean");
break;
}
// Output: "String one"
// Switch uses strict comparison
const value = 0;
switch (value) {
case false: // false (0 !== false)
console.log("False");
break;
case 0: // true (0 === 0)
console.log("Zero");
break;
}
// Output: "Zero"
// Equivalent if-else
if (value === false) {
console.log("False");
} else if (value === 0) {
console.log("Zero");
}
Value | switch case | if (==) | if (===) | Explanation |
---|---|---|---|---|
"5" vs 5 | false | true | false | Switch uses strict comparison |
0 vs false | false | true | false | No type coercion in switch |
"" vs 0 | false | true | false | Switch doesn’t convert types |
null vs undefined | false | true | false | Strict comparison in switch |
1 vs true | false | true | false | Different types for switch |
"hello" vs "hello" | true | true | true | Identical strings |
NaN vs NaN | false | false | false | NaN is not equal to itself |
Fall-through — code execution continues until the first break
or end of block:
const day = "monday";
switch (day) {
case "monday":
console.log("Start of week");
// NO break! Continue execution
case "tuesday":
console.log("Working day");
break;
case "saturday":
case "sunday":
console.log("Weekend");
break;
}
// Output:
// "Start of week"
// "Working day"
// Grouping cases
function getSeasonByMonth(month) {
switch (month) {
case "december":
case "january":
case "february":
return "Winter";
case "march":
case "april":
case "may":
return "Spring";
case "june":
case "july":
case "august":
return "Summer";
case "september":
case "october":
case "november":
return "Autumn";
default:
return "Unknown month";
}
}
console.log(getSeasonByMonth("january")); // "Winter"
⚠️ Warning! Forgotten break
can lead to unexpected behavior:
// ❌ Error: forgot break
function processGrade(grade) {
switch (grade) {
case "A":
console.log("Excellent!");
// Forgot break!
case "B":
console.log("Good!");
break;
case "C":
console.log("Satisfactory");
break;
default:
console.log("Need improvement");
}
}
processGrade("A");
// Output:
// "Excellent!"
// "Good!" (undesirable!)
function handleHttpStatus(status) {
switch (status) {
case 200:
case 201:
case 204:
return "Success";
case 400:
return "Bad Request";
case 401:
return "Unauthorized";
case 403:
return "Forbidden";
case 404:
return "Not Found";
case 500:
case 502:
case 503:
return "Server Error";
default:
return `Unknown status: ${status}`;
}
}
console.log(handleHttpStatus(200)); // "Success"
console.log(handleHttpStatus("200")); // "Unknown status: 200"
function calculate(a, operator, b) {
switch (operator) {
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
if (b === 0) {
throw new Error("Division by zero");
}
return a / b;
case "**":
case "^":
return Math.pow(a, b);
default:
throw new Error(`Unknown operator: ${operator}`);
}
}
console.log(calculate(5, "+", 3)); // 8
console.log(calculate(10, "/", 2)); // 5
function validateInput(value, expectedType) {
const actualType = typeof value;
switch (expectedType) {
case "string":
if (actualType === "string" && value.length > 0) {
return { valid: true, message: "Valid string" };
}
return { valid: false, message: "Expected non-empty string" };
case "number":
if (actualType === "number" && !isNaN(value)) {
return { valid: true, message: "Valid number" };
}
return { valid: false, message: "Expected number" };
case "boolean":
if (actualType === "boolean") {
return { valid: true, message: "Valid boolean" };
}
return { valid: false, message: "Expected boolean" };
case "array":
if (Array.isArray(value)) {
return { valid: true, message: "Valid array" };
}
return { valid: false, message: "Expected array" };
default:
return { valid: false, message: `Unknown type: ${expectedType}` };
}
}
console.log(validateInput("hello", "string")); // { valid: true, ... }
console.log(validateInput(42, "string")); // { valid: false, ... }
const value = 1;
switch (value) {
case "1":
console.log("String");
break;
case 1:
console.log("Number");
case true:
console.log("Boolean");
break;
default:
console.log("Other");
}
Output:
Explanation:
value = 1
strictly equals case 1
, so this block executesbreak
after case 1
, so execution continuescase true
executes (fall-through)break
stops executionfunction getDayType(day) {
switch (day) {
case "monday":
case "tuesday":
case "wednesday":
case "thursday":
case "friday":
return "Working day";
case "saturday":
case "sunday":
return "Weekend";
}
}
console.log(getDayType("monday")); // ?
console.log(getDayType("MONDAY")); // ?
console.log(getDayType("mon")); // ?
Result:
getDayType("monday")
→ "Working day"
getDayType("MONDAY")
→ undefined
getDayType("mon")
→ undefined
Problems:
default
caseFixed version:
function getDayType(day) {
const normalizedDay = day.toLowerCase();
switch (normalizedDay) {
case "monday":
case "mon":
case "tuesday":
case "tue":
case "wednesday":
case "wed":
case "thursday":
case "thu":
case "friday":
case "fri":
return "Working day";
case "saturday":
case "sat":
case "sunday":
case "sun":
return "Weekend";
default:
return "Unknown day";
}
}
const score = "85";
switch (true) {
case score >= 90:
console.log("A");
break;
case score >= 80:
console.log("B");
break;
case score >= 70:
console.log("C");
break;
default:
console.log("F");
}
Output: "F"
Explanation:
score = "85"
(string)"85" >= 90
→ false
"85" >= 80
→ true
, but true !== true
in switch contexttrue
default
triggersCorrect approach:
const score = Number("85"); // Convert to number
if (score >= 90) {
console.log("A");
} else if (score >= 80) {
console.log("B");
} else if (score >= 70) {
console.log("C");
} else {
console.log("F");
}
// ❌ Problematic function
function getDiscountByCategory(category, isPremium) {
switch (category) {
case "electronics":
if (isPremium) {
return 0.15;
}
return 0.10;
case "clothing":
if (isPremium) {
return 0.20;
}
return 0.15;
case "books":
return 0.05;
}
}
console.log(getDiscountByCategory("electronics", true)); // ?
console.log(getDiscountByCategory("unknown", false)); // ?
Problems:
default
caseundefined
Fixed version:
function getDiscountByCategory(category, isPremium = false) {
// Input validation
if (typeof category !== "string") {
throw new Error("Category must be a string");
}
if (typeof isPremium !== "boolean") {
throw new Error("isPremium must be boolean");
}
const normalizedCategory = category.toLowerCase();
switch (normalizedCategory) {
case "electronics":
return isPremium ? 0.15 : 0.10;
case "clothing":
return isPremium ? 0.20 : 0.15;
case "books":
return 0.05; // Same discount for all
default:
return 0; // No discount for unknown categories
}
}
// Alternative approach with object
const DISCOUNTS = {
electronics: { regular: 0.10, premium: 0.15 },
clothing: { regular: 0.15, premium: 0.20 },
books: { regular: 0.05, premium: 0.05 }
};
function getDiscountByCategory2(category, isPremium = false) {
const categoryData = DISCOUNTS[category.toLowerCase()];
if (!categoryData) {
return 0;
}
return isPremium ? categoryData.premium : categoryData.regular;
}
// ✅ Many specific values
function getHttpStatusText(code) {
switch (code) {
case 200: return "OK";
case 201: return "Created";
case 400: return "Bad Request";
case 401: return "Unauthorized";
case 403: return "Forbidden";
case 404: return "Not Found";
case 500: return "Internal Server Error";
default: return "Unknown Status";
}
}
// ✅ Grouping similar cases
function isWeekend(day) {
switch (day.toLowerCase()) {
case "saturday":
case "sunday":
return true;
default:
return false;
}
}
// ✅ State machine
function processState(currentState, action) {
switch (currentState) {
case "idle":
switch (action) {
case "start": return "running";
case "reset": return "idle";
default: return currentState;
}
case "running":
switch (action) {
case "pause": return "paused";
case "stop": return "stopped";
default: return currentState;
}
// ... other states
}
}
// ✅ Value ranges
function getGrade(score) {
if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else if (score >= 70) {
return "C";
} else if (score >= 60) {
return "D";
} else {
return "F";
}
}
// ✅ Complex conditions
function canAccessResource(user, resource) {
if (user.isAdmin) {
return true;
} else if (user.role === "moderator" && resource.type === "public") {
return true;
} else if (user.id === resource.ownerId) {
return true;
} else {
return false;
}
}
// ✅ Conditions with logical operators
function shouldShowNotification(user, notification) {
if (user.preferences.notifications &&
!user.isDoNotDisturb &&
notification.priority === "high") {
return true;
}
return false;
}
// Instead of switch
function getAnimalSound(animal) {
switch (animal) {
case "dog": return "Woof!";
case "cat": return "Meow!";
case "cow": return "Moo!";
case "pig": return "Oink!";
default: return "Unknown sound";
}
}
// ✅ Modern approach
const ANIMAL_SOUNDS = {
dog: "Woof!",
cat: "Meow!",
cow: "Moo!",
pig: "Oink!"
};
function getAnimalSound(animal) {
return ANIMAL_SOUNDS[animal] ?? "Unknown sound";
}
// ✅ Map with functions
const ACTION_HANDLERS = new Map([
["CREATE", (data) => createItem(data)],
["UPDATE", (data) => updateItem(data)],
["DELETE", (data) => deleteItem(data)],
["READ", (data) => readItem(data)]
]);
function handleAction(action, data) {
const handler = ACTION_HANDLERS.get(action.toUpperCase());
if (handler) {
return handler(data);
}
throw new Error(`Unknown action: ${action}`);
}
// ✅ Object-oriented approach
class Shape {
calculateArea() {
throw new Error("Method must be implemented");
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
calculateArea() {
return Math.PI * this.radius ** 2;
}
}
class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}
calculateArea() {
return this.width * this.height;
}
}
// Usage
function getArea(shape) {
return shape.calculateArea(); // Polymorphism instead of switch
}
// ✅ Good: explicit break
switch (action) {
case "save":
saveData();
break;
case "load":
loadData();
break;
default:
showError();
break; // Even in default for consistency
}
// ❌ Bad: forgotten break
switch (action) {
case "save":
saveData();
// Forgot break!
case "load":
loadData(); // Will execute for "save" too!
break;
}
// ✅ Good: handle all cases
function processUserRole(role) {
switch (role) {
case "admin":
return { permissions: ["read", "write", "delete"] };
case "user":
return { permissions: ["read"] };
case "guest":
return { permissions: [] };
default:
throw new Error(`Unknown role: ${role}`);
}
}
// ❌ Bad: no default
function processUserRoleBad(role) {
switch (role) {
case "admin":
return { permissions: ["read", "write", "delete"] };
case "user":
return { permissions: ["read"] };
}
// What if role = "guest"? Returns undefined!
}
// ✅ Good: logical grouping
function getBusinessHours(day) {
switch (day.toLowerCase()) {
case "monday":
case "tuesday":
case "wednesday":
case "thursday":
case "friday":
return "9:00 - 18:00";
case "saturday":
return "10:00 - 16:00";
case "sunday":
return "Closed";
default:
return "Unknown day";
}
}
// ❌ Bad: complex logic in case
switch (userType) {
case "premium":
if (user.subscriptionActive && user.paymentValid) {
if (user.lastLogin > Date.now() - 30 * 24 * 60 * 60 * 1000) {
return getPremiumFeatures();
} else {
return getBasicFeatures();
}
}
break;
// ...
}
// ✅ Good: extract logic to functions
function isPremiumActive(user) {
return user.subscriptionActive &&
user.paymentValid &&
user.lastLogin > Date.now() - 30 * 24 * 60 * 60 * 1000;
}
switch (userType) {
case "premium":
return isPremiumActive(user) ? getPremiumFeatures() : getBasicFeatures();
case "basic":
return getBasicFeatures();
default:
return getGuestFeatures();
}
// .eslintrc.json
{
"rules": {
"default-case": "error", // Requires default
"no-fallthrough": "error", // Warns about fall-through
"no-case-declarations": "error" // Prohibits declarations in case
}
}
// ❌ Error
function getPrice(category) {
let price = 0;
switch (category) {
case "basic":
price = 10;
// Forgot break!
case "premium":
price = 20;
break;
case "enterprise":
price = 50;
break;
}
return price;
}
console.log(getPrice("basic")); // 20 instead of 10!
// ❌ Error: variables "hoist"
switch (type) {
case "A":
let result = "Type A"; // Error!
break;
case "B":
let result = "Type B"; // Error: redeclaration!
break;
}
// ✅ Correct: use blocks
switch (type) {
case "A": {
let result = "Type A";
console.log(result);
break;
}
case "B": {
let result = "Type B";
console.log(result);
break;
}
}
// ❌ Error: expecting type coercion
const userInput = "1";
switch (userInput) {
case 1: // Won't work! "1" !== 1
console.log("One");
break;
}
// ✅ Correct: convert type beforehand
const userInputNumber = Number(userInput);
switch (userInputNumber) {
case 1:
console.log("One");
break;
}
// ❌ Bad: switch not suitable for ranges
switch (true) {
case age >= 18 && age < 65:
return "Adult";
case age >= 65:
return "Senior";
default:
return "Child";
}
// ✅ Good: use if-else
if (age >= 65) {
return "Senior";
} else if (age >= 18) {
return "Adult";
} else {
return "Child";
}
// For many conditions switch can be faster
function getColorHex(color) {
// Switch: O(1) in best case (jump table)
switch (color) {
case "red": return "#FF0000";
case "green": return "#00FF00";
case "blue": return "#0000FF";
case "yellow": return "#FFFF00";
case "purple": return "#800080";
case "orange": return "#FFA500";
case "pink": return "#FFC0CB";
case "brown": return "#A52A2A";
default: return "#000000";
}
}
// If-else: O(n) in worst case
function getColorHexIfElse(color) {
if (color === "red") return "#FF0000";
else if (color === "green") return "#00FF00";
else if (color === "blue") return "#0000FF";
else if (color === "yellow") return "#FFFF00";
else if (color === "purple") return "#800080";
else if (color === "orange") return "#FFA500";
else if (color === "pink") return "#FFC0CB";
else if (color === "brown") return "#A52A2A";
else return "#000000";
}
// Object: O(1) always
const COLOR_MAP = {
red: "#FF0000",
green: "#00FF00",
blue: "#0000FF",
yellow: "#FFFF00",
purple: "#800080",
orange: "#FFA500",
pink: "#FFC0CB",
brown: "#A52A2A"
};
function getColorHexObject(color) {
return COLOR_MAP[color] ?? "#000000";
}
Key points about switch:
===
, doesn’t convert typesbreak
When to use:
Modern alternatives:
Remember: Switch is a powerful tool, but not a universal solution. Choose the right tool for each task!
Want more articles for interview preparation? Subscribe to EasyAdvice, bookmark the site and level up every day 💪