JS Sketchbooksee JavaScript think ✏️
← back to phase 2

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.

watch it happen
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.

a fork that hands you a VALUEage >= 18 ?"adult""minor"
under the hood

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.

your turn

✏️ 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.

💼 on the job

One day, you will read test code like this:

✎ pull request · login.spec.js
const timeout = config.timeout ?? 30000;
if (element && element.click()) { ... }

Real test code reads like short sentences once you know ?? and &&.

teach it back

🗣️ 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.

a few sentences, minimum — you’ve got this
to remember
Ternary = a fork that yields a VALUE: condition ? whenTrue : whenFalse. Great inline, terrible nested.
|| returns the first truthy VALUE (default idiom) — but stomps legit 0/"" ; ?? only falls back on null/undefined.
&& returns the first falsy side and never evaluates past it — the guard idiom that makes crashes unreachable.
next: 2.5 while loops →