The conditional operator, usually called the ternary, is a one-line shorthand for a simple if...else. The big difference: if...else runs blocks of code, while the ternary produces a value. That means you can use it anywhere a value fits: on the right of =, inside console.log(), or in the middle of a string.
let age = 15;
let text = (age < 18) ? "Minor" : "Adult";
console.log(text);
(condition) ? expression1 : expression2
| Part | What it is |
|---|---|
| condition | The test: any expression that is true or false (or truthy/falsy) |
| ? | Separates the condition from the two results |
| expression1 | The value you get if the condition is true |
| : | Separates the two results |
| expression2 | The value you get if the condition is false |
Read it as a question: "is the condition true? If yes, this. Otherwise, that." All four parts are required; there is no ternary without the : part.
It is called ternary because it takes three operands (the condition and two results). It is the only JavaScript operator that does. The parentheses around the condition are optional, but they make it easier to read. The ternary has worked in every browser since 1997.
This is the ternary's main job. Here is a member discount, where the value stored depends on a boolean:
let isMember = true;
let discount = isMember ? 0.2 : 0;
console.log(discount);
Set isMember to false and discount becomes 0. Compare it with the if...else it replaces:
// if...else: 6 lines, and the variable is named three times
let discount;
if (isMember) {
discount = 0.2;
} else {
discount = 0;
}
// ternary: 1 line, same result
let discount = isMember ? 0.2 : 0;
A bonus: with the ternary, discount gets its value on the same line it is declared, so it can be a const. The if...else version has to use let.
Because the ternary is a value, you do not have to store it first. You can pass it straight to console.log():
let score = 55;
console.log(score >= 60 ? "Pass" : "Fail");
Or build it into a string, which is perfect for plurals:
let count = 3;
console.log("You have " + count + " item" + (count !== 1 ? "s" : ""));
With count = 1, the ternary gives an empty string and the output is You have 1 item.
+ runs first, gluing "You have 3 item" + count into one string. That string becomes the condition, which is truthy, so the whole line logs just s. Whenever a ternary sits inside a bigger expression, wrap it in parentheses.
The ternary is for choosing a value. Do not use it just to decide which action to run:
// Works, but awkward: nothing is done with the result
isAdmin ? console.log("Show panel") : console.log("Go home");
// Clearer: if...else is built for running actions
if (isAdmin) {
console.log("Show panel");
} else {
console.log("Go home");
}
And if either side needs more than one statement, the ternary cannot hold it at all. Use if...else.
if...else instead. The ternary's whole value is being quick to read; once it stops being quick to read, it costs more than it saves.
The value after : can itself be another ternary, which gives you an else if-style chain:
let score = 82;
let grade = score >= 90 ? "A"
: score >= 80 ? "B"
: "C or below";
console.log(grade);
Like else if, it is checked top to bottom and the first true condition wins. Formatted one condition per line like this, two or three levels is readable. Crammed onto one line, or deeper than that, it gets confusing fast; use if...else if instead.
What does let fee = 10 > 5 ? "high" : "low"; store in fee?
true"high""low"1010 > 5 is true, so the ternary gives the value before the colon. The true from the comparison is used to choose; it is not the result.Which of these is not a good job for a ternary?
label to "on" or "off"if...else blocks are for.What does this log?
let lives = 0;
console.log(lives ? "Keep going" : "Game Over");
Game Over. The condition does not need to be a comparison. 0 is falsy, so the ternary picks the value after the colon.period to "day" or "night" based on hour. Log itconsole.log to print "1 result" or "N results" for any count. Test with 1 and 5if...else if...else. Which do you find easier to read?