A ternary can be split into three parts:
const result = weight > 100 ? 'very heavy' : 'fairly light';
// | condition | value 1 | value 2 |
(Some learners put parens around each of the three, or even a set around the entire ternary to make it clear that it's all going to be one value. The parens are rarely syntactically necessary, but they can be helpful to reasoning about the three parts.)
So let's break it down:
- The conditon. This part should evaluate to a boolean, a
true
orfalse
. - Value 1. This is the value that the entire thing will evaluate to IF the condition evaluated to
true
. Otherwise, this value gets thrown away. - Value 2. This is the value that the entire thing will evaluate to IF the condition evaluated to
false
. Otherwise, this value gets thrown away.
It helps to think of this in terms of its translation from an if/else
statment:
let result;
if (weight > 100) {
result = 'very heavy';
} else {
result = 'pretty light';
}
These two examples will give you the exact same result (although the ternary does allow you to use const
!), but, of course, the if
takes many more lines.
Another useful comparison is the binary math operators:
const sum = 5 + 3;
const product = 8 * 6;
const mod = 11 % 2;
Like the ternary operator, these binary operators always resolve to one value. It's easier for us to see that with operators we're used to, but you'll get used to that takeaway about ternaries soon enough!
The things to keep in mind about ternaries, in order of how often you'll forget when learning them:
- They always resolve to one value.
- Because they're resolving to a value, you have to DO something with that value for them to mean anything.
- You do NOT want to do anything in a ternary BESIDES resolve to values.
- Forgetting To USE The Value
// BAD
weight > 100 ? 'very heavy' : 'fairly light';
This example doesn't do anything with the value we're resolving to. Besides putting that value in a variable, we might do one of the following with it:
// GOOD
console.log(weight > 100 ? 'very heavy' : 'fairly light');
someArr.push(weight > 100 ? 'very heavy' : 'fairly light');
return weight > 100 ? 'very heavy' : 'fairly light';
In each of these cases, you're doing something not with the ternary itself, but with the one value it evaluates to, depending on the condition at the start.
- Performing A Side Effect
weight > 100 ? writeToDB() : readFromDB();
weight > 100 ? console.log('very heavy') : console.log('fairly light');
weight > 100 ? someArr.push('very heavy') : someArr.push('fairly light');
weight > 100 ? return 'very heavy' : return 'fairly light';
If you're doing the first example there, running different functions in different cases, what you really want to do is an if/else
. Yes, it would be slightly longer, but it's a more clear way to write it, and anyone reading a ternary written this way (including yourself a week later!) is going to at best waste a moment re-reading your code to understand its non-standard ternary use, and at worst NOT take that moment, and instead misunderstand what the code does.
The next three examples up there have the exact same result as the three examples in the previous section, but do it with one clear action at the start of the line, performed on the value the ternary evaluates to, as opposed to two actions, one for each value the ternary could evaluate to, and hidden in the middle of the line.
What it boils down to is that there are standards to making an easy-to-read ternary--well, easy to read once you get used to the syntax and concept!--and if you don't follow them, you'll end up with a hard-to-read ternary.
- Nested Ternaries
Just don't do them! They can be very difficult to read.
// BAD please don't do this
const result1 = weight > 100 ? 'very heavy' : weight > 50 ? 'kind of heavy' : 'fairly light';
const result2 = weight < 100 ? weight > 50 ? 'kind of heavy' : 'fairly light' : 'very heavy';
It's generally accepted that nested ternaries are very difficult to read. Both of these examples do the same thing as this, clearer version using if/else
:
let result;
if (weight > 100) {
result = 'very heavy';
} else if (weight > 50) {
result = 'kind of heavy';
} else {
result = 'fairly light';
}
There are other alternatives to nested ternaries. Just... not nested ternaries.
Just... no. Please.
Do not use if
for any of the below. Only ternaries!
- Write a function called
isItColin
that, given the stringColin
, returns the stringYes, that is Colin.
and otherwise returns the stringNo, that is not Colin.
. - Write a function called
isHot
that returns the stringYes, it is indeed hot.
if the temperature is at or above 80, and the stringNo, it is not hot.
otherwise. - Write a function called
helloThere
that returns a short greeting given a name with more than 5 characters and a longer greeting given a name of 5 characters or fewer. The short greeting should be the stringHi
and the given name, separated by a comma and a space. The long greeting should be the stringHello
and the given name, separated by a comma and a space. - Write a function called
goodbyeYou
that, given a name, returns the stringGoodbye
followed by the name, with a comma and space in between. If no parameter is given, substitute the stringstranger
for their name. - Write a function called
darkAndStormyNight
that returns the stringIt was a dark and stormy night.
only if the first parameter is the stringdark
AND the second parameter, representing the rainfall in inches, is greater than0.5
. If either isn't true, return the stringMy usual opening doesn't apply, I guess.