2.4 — Ternary & short-circuit
if/else decides which code runs. But often you just need to decide which value to use — “adult or minor?”, “their nickname or a default?”. For that, JavaScript has decisions that are expressions: the ternary operator.
And a secret lesson 1.10 already whispered: || and && don’t return manufactured booleans, they return one of their own sides. Today that secret becomes two of the most-used idioms in all of JavaScript.
let age = 20; let label = age >= 18 ? "adult" : "minor"; console.log(label); let nickname = "" || "Anonymous"; console.log(nickname); let user = null; console.log(user && user.name);
Line 2, read aloud: “age at least 18? then "adult", otherwise "minor".” Anatomy: condition ? valueIfTrue : valueIfFalse. It’s a fork — but instead of choosing a road, it chooses a VALUE, and the whole expression becomes that value.
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
The deep idea unifying this lesson: expressions compose. A ternary is an expression, so it can live anywhere a value can. Inside a template slot (`You are ${age >= 18 ? "in" : "out"}`). Inside an argument. Inside another expression. Statements (if/else) cannot do that — they do not become anything. Knowing which tool produces a value and which performs an action is a quiet superpower for reading code.
The exact return rules, for reference: a || b → a if a is truthy, else b. a && b → a if a is falsy, else b. a ?? b → a unless a is null/undefined, else b.
All three short-circuit: the right side isn’t just ignored — it’s never evaluated, side effects and all.
Fun fact: the ?: operator is older than almost everything you have learned. It comes from the C language (1972) — JavaScript borrowed its syntax from C wholesale: braces, semicolons, for loops, switch… and this. The ?? operator is the opposite: one of the newest things in this curriculum, added to JavaScript in 2020. A 48-year age gap, between two operators that sit three lines apart in our code.
✏️ Quick check 1
Type the value of fee:
let age = 3; let fee = age < 5 ? 0 : 100;
✏️ Quick check 2
The user deliberately chose volume 0. Type what setting ends up as:
let volume = 0; let setting = volume || 50;
✏️ Quick check 3
Same guard, new data: type what 0 && "pizza" evaluates to.
One day, you will read test code like this:
const timeout = config.timeout ?? 30000;if (element && element.click()) { ... }
Real test code reads like short sentences once you know ?? and &&.
🗣️ Now teach it back
Explain to a friend: how does a ternary differ from if/else, and how do the || default and && guard idioms work — including the 0-gets-stomped trap and which operator fixes it?
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.