π Switch to Object Literals
- Published on
switch
statement is one of the things that has been around for ages, and is taught in most programming 101 lessons. It has a concise syntax, has a fixed depth, (unlike the nested if-else-if hell), and an optimized implementation may execute faster than the traditional if-else statement.
Objects are the foundation of JavaScript. Nearly everything in JavaScript is an object other than things that are not objects which are β null
, undefined
, strings
, numbers
, boolean
, and symbols
.
In this post, I'll show how I use Objects instead of switch
statement in JavaScript.
Why though?
There are some things about switch
statement that bums me out:
-
Missed a
break
in a long list of switch cases? Now the software is broken π¨ -
Because
switch
does not mandate using braces, we have to deal with hoisting π€·π½ββοΈswitch (type) { case 'beer': let item = 'πΊ' console.log(item) break case 'whiskey': let item = 'π₯' console.log(item) break default: console.log('π₯') }
This code leads to a π
Uncaught SyntaxError: Identifier 'item' has already been declared
This returns an error because the variable
item
has already been declared in the first case and since it does not have curly brackets it's being hoisted, then by the moment the second case tries to declare it, it already exists and π₯.
Objects, on the other hand, are much more flexible, have better readability and maintainability, and we donβt need to manually break;
each βcaseβ. It's not like I hate switch
statements. I deal with Objects regularly, so it's only natural that I use Objects to evaluate expressions which require a lookup.
Example
Let's say we have a method which returns an emoji for a text which user has entered. Using a switch
statement, this is how it looks
function getEmoji(text) {
switch (text) {
case 'beer':
return 'πΊ'
case 'whiskey':
return 'π₯'
case 'wine':
return 'π·'
default:
return 'π₯'
}
}
const emoji = getEmoji('beer') // => πΊ
As the number of cases
increases, the switch has to evaluate each case until it hits a match and a break
/return
. The order of the cases
also matters.
Now an Object which does the same thing as the switch
statement:
function getEmoji(text) {
const emojiMap = {
beer: 'πΊ',
whiskey: 'π₯',
wine: 'π·',
default: 'π₯',
}
return emojiMap[text] || emojiMap['default']
}
Fall Through cases
switch
statements support fall through. Which means more than one case can apply to a specific piece of code.
function getDrinkType(text) {
switch (text) {
case 'beer':
case 'whiskey':
return 'Hard Drink'
case 'coke':
case 'pepsi':
return 'Soft Drink'
default:
return 'Not a clue!'
}
}
const drink = getDrinkType('whiskey') // => 'Hard Drink'
We let coke
and pepsi
"fall through" by not adding a return
statement between the cases.
const HARD_DRINK = 'Hard Drink'
const SOFT_DRINK = 'Soft Drink'
function getDrinkType(text) {
const drinkMap = {
beer: HARD_DRINK,
whiskey: HARD_DRINK,
wine: SOFT_DRINK,
default: 'Not a clue!',
}
return drinkMap[text] || drinkMap['default']
}
const drink = getDrinkType('whiskey') // => 'Hard Drink'
Doing this for Object Literals is simple and more declarative - as well as being less prone to error. Our code suddenly becomes much more structured, readable and reusable.
Conclusion
This was a very trivial example, and you might say the switch
statement looks better here. I agree. The point of this article was not to bash switch
statement, but rather show how you can use the flexibility of Object Literals to achieve the same thing instead of using a switch
. Objects are more extensible, maintainable, and we can test them a lot better.
Object literals can contain functions as well as any other Objects, which makes them really flexible!
Again, this comes down to purely a personal preference and YMMV. If you feel like you can be productive with
switch
instead of Objects, go for it!