There are a couple of areas we as developers could improve our JavaScript code by dropping if
and switch
statements and using ternaries instead. Allow me to demonstrate!
Conditional Assignment
When doing conditional assignment, use ternaries. So instead of:
let resultif (operator === ‘+’) {
result = left + right
} else if (operator === ‘*’) {
result = left * right
} else if (operator === ‘-’) {
result = left — right
} else {
result = left / right
}
Do:
const result =
operator === ‘+’ ? left + right
: operator === ‘*’ ? left * right
: operator === ‘-’ ? left — right
: left / right
Why?
- Less code.
- Prefers
const
overlet
. (See Eric Elliot on why we should do this.) - Avoids side effects (i.e. assigning value of variable outside block scope).
Similar to a key-value map, we map one condition to one return value on each line.
Conditional Function Calls
Ternaries are designed to return a value, and if you can use them for variable assignment, that’s great! But sometimes you need a control structure for conditional execution of code to perform side effects, and ternaries can help here, too. Instead of:
if (conditionA) {
outcome1()
} else if (conditionB) {
if (conditionC) {
outcome2()
} else {
outcome3()
}
} else {
outcome4()
}
Do:
conditionA ? outcome1()
: conditionB && conditionC ? outcome2()
: conditionB ? outcome3()
: outcome4()
Why?
Again, less code.
Notice also that in this case our if
s were nested, but we refactored our ternary for less cognitive load. With nested logic, we must be aware of the inner context and each outer context. Although this is a “nested ternary”, we don’t have to use nested thinking. Since each line has a single condition and outcome, in practice you can focus on one line at a time. Once you’ve ruled out a prior condition you can safely ignore it. We could have done this with our if
as well:
if (conditionA) {
outcome1()
} else if (conditionB && conditionC) {
outcome2()
} else if (conditionB) {
outcome3()
} else {
outcome4()
}
It’s better than before! But again, the ternary form is terser. Less to read, and less to maintain.
(Notice that this refactor to reduce cognitive load also applies to conditional assignment, or anywhere you are using nested logic which would lend itself to refactoring in this way.)
Of course, you could also use switch
for your conditional assignment and your side effects:
let result;switch (operator) {
case '+':
result = left + right
break
case '*':
result = left * right
break
case '-':
result = left - right
break
default:
result = left / right
}...switch (true) {
case conditionA:
outcome1()
break
case conditionB && conditionC:
outcome2()
break
case conditionB:
outcome3()
break
default:
outcome4()
}
But again, we have more code, meaning more to read and maintain, and there’s also more surface area in which bugs can hide — bugs such as the ones you’ll get when forgetting to include the break
statement on each case
except the default
. And we’re still using let
to assign a variable outside the block scope.
I hope I’ve convinced you that there is ample opportunity to improve our code with the use of ternaries. If not, let me know why in the comments!
This article was inspired by Eric Elliott’s Nested Ternaries are Great.
✉️ Subscribe to Codeburst’s once-weekly Email Blast, 🐦 Follow Codeburst on Twitter, and 🕸️ Learn Full Stack Web Development.
You can follow me on Twitter @okaybenji