🚫 Stop Using Switch Statements — Use a Lookup Object Instead 🧠
Switch statements have been around forever. They’re familiar, readable (for small blocks), and often the first thing we reach for when branching logic is needed.
But let’s be honest — in real-world projects, they don’t scale.
As soon as your logic grows beyond 3–4 cases, switch-case blocks become:
- Verbose
- Repetitive
- Hard to test
- Painful to maintain
Let me show you a better, cleaner pattern that’s not only shorter — but also more flexible, testable, and production-friendly.
🔥 The Problem With Switch Statements
Here’s a common example I’ve seen (and written myself) far too many times:
function getRoleLabel(role) {
switch (role) {
case 'admin':
return 'Administrator';
case 'editor':
return 'Editor';
case 'viewer':
return 'Viewer';
default:
return 'Unknown';
}
}
Looks harmless, right?
But now imagine your roles change, your labels get translated, or you need to return icon names or color codes too. Suddenly, you’re maintaining multiple switch blocks across different files for the same mapping.
This isn’t just messy — it’s fragile.
✅ A Cleaner Alternative — The Lookup Object Pattern
Let’s rewrite that same function using a simple object map:
const roleLabels = {
admin: 'Administrator',
editor: 'Editor',
viewer: 'Viewer'
};
function getRoleLabel(role) {
return roleLabels[role] || 'Unknown';
}
That’s it. Done.
✨ Benefits:
- Shorter and cleaner
- Easy to add or remove values
- Supports dynamic logic (load from config or CMS)
- Testable in isolation
🛠 Real-World Example From a Dashboard Project
I recently worked on a React-based dashboard for managing user roles.
Instead of this:
switch (user.status) {
case 'active':
return '🟢 Active';
case 'inactive':
return '⚪ Inactive';
case 'banned':
return '🔴 Banned';
default:
return '❓ Unknown';
}
We used:
const statusEmoji = {
active: '🟢 Active',
inactive: '⚪ Inactive',
banned: '🔴 Banned'
};
const getStatusLabel = (status) => statusEmoji[status] || '❓ Unknown';
This gave us centralized control , allowed product managers to tweak labels without logic changes, and made it easier to write tests like:
expect(getStatusLabel('active')).toBe('🟢 Active');
Simple. Powerful. Clean.
⚙️ Advanced Pattern: Function Lookup Tables
Let’s say you’re handling user actions on the backend using Express or on the frontend in a reducer-style function.
Instead of:
switch (action) {
case 'login': return loginUser();
case 'logout': return logoutUser();
case 'signup': return signupUser();
default: return null;
}
Use this pattern:
const actionMap = {
login: loginUser,
logout: logoutUser,
signup: signupUser
};
const runAction = (type) => (actionMap[type] || (() => null))();
This makes it:
- Easy to test individual handlers
- Scalable for adding/removing actions
- Avoids code duplication
⛔ When Not to Use This Pattern
To be clear, switch statements aren’t evil.
If each case involves radically different and unrelated logic , or needs to fall through, a switch may still be more appropriate.
But in 90% of real-world UI/logic scenarios, especially those involving mappings, enums, or configs — this pattern is a no-brainer win.
🔚 Final Thoughts
switch-case blocks served us well… back in 2015.
But in modern JavaScript codebases, they’re often a signal that something could be refactored and cleaned up.
Lookup objects are the functional, testable, and elegant way forward.
They help you:
- Centralize logic
- Improve maintainability
- Write cleaner code with fewer bugs
So next time you’re about to write a switch — ask yourself:
Can this be a map instead?
🙌 Bonus Tip
This pattern pairs beautifully with:
- Internationalization (i18n)
- Theme-based UI mapping
- Role-based access control (RBAC)
- Feature toggles
📣 Like This Pattern? Here’s More
I regularly share JavaScript patterns, clean code tricks, and real-world dev insights.
👉 Visit sachinkasana-dev.vercel.app for more.
💬 Or connect with me on LinkedIn for weekly developer tips!