Operators & Expressions
Beginner · 18 min read · ▶ live playground · ✦ checkpoint
A program that can't ask questions can't make decisions. JavaScript operators and expressions are how your code asks yes-or-no questions, combines the answers, and picks one value before you reach the bigger decision syntax in lesson 4.3.
An expression is a piece of code that produces a value, and an operator is a symbol or keyword that works with values to produce a new value. You already know arithmetic operators like + and *; now you'll use operators that answer questions.
Comparisons ask yes-or-no questions
A comparison operator compares two values and produces a boolean, a value that is only true or false. Think of a comparison like a scoreboard judge: it looks at two numbers or labels, then raises exactly one card — yes or no.
const playerScore = 84;
const passMark = 70;
const perfectScore = 100;
console.log(playerScore >= passMark);
console.log(playerScore > 90);
console.log(playerScore < perfectScore);
const enteredPin = "1234";
const savedPin = "1234";
console.log(enteredPin === savedPin);
console.log(enteredPin !== "0000");→ true, false, true, true, true.
The comparison family is small:
>means greater than.>=means greater than or equal to.<means less than.<=means less than or equal to.===means same value and same type.!==means not the same value or not the same type.
This lesson uses === and !== as your normal equality tools. The next lesson owns equality deeply, including why JavaScript's older loose equality operator causes traps.
Logic combines answers
A logical operator combines or flips boolean answers. If comparisons are yes-or-no questions, logical operators are the decision checklist you write beside them.
const age = 16;
const hasTicket = true;
const hasSignedPass = false;
const canEnter = age >= 13 && hasTicket;
const needsAdult = age < 18 && !hasSignedPass;
const canEnterAlone = age >= 18 || hasSignedPass;
console.log(canEnter);
console.log(needsAdult);
console.log(canEnterAlone);→ true, true, false.
Read them aloud:
a && bmeansaandbmust both pass.a || bmeansaorbcan pass.!ameans nota; it flipstruetofalseandfalsetotrue.
In needsAdult, the left side asks age < 18, and the right side asks !hasSignedPass. Both are true, so the whole expression is true.
Short-circuiting is a feature
Short-circuit evaluation means JavaScript stops reading a logical expression as soon as the final answer is already known. It is like checking a guest list at the door: if the guest has no ticket, you don't waste time asking which seat they booked.
const hasTicket = false;
console.log(hasTicket && seatNumber);
const isMember = true;
console.log(isMember || guestPass);→ false, then true. seatNumber and guestPass were never read, so there is no ReferenceError.
That is not a trick. It is one of the reasons && and || are useful. The left side can protect the right side from being read too early.
One beginner surprise: && and || return the value that decided the result, not always a cleaned-up true or false. When both sides are already booleans, you mostly won't notice. When you use them for defaults, you will.
Try it — default only when missing
|| is often used as a fallback: "use the left value, or use this backup." But || cares about truthiness: truthy means treated like true, and falsy means treated like false. The next lesson gives you the full map; for now, know that an empty string is falsy.
Nullish coalescing ?? means "use the backup only when the left side is null or undefined." It is like a spare name tag you hand out only when the original slot is empty, not when someone chooses to leave the name blank. Those two values are the missing-value signals you met in Section 2, so ?? is the better default operator when blank, 0, or false might be real user choices.
The brackets make the empty nickname visible. || replaces it with "Player One" because an empty string acts false. ?? keeps it because the nickname is not missing; it is a real, intentionally blank string.
Ternary picks one of two values
The ternary operator is a three-part expression that chooses one of two values: condition ? valueIfTrue : valueIfFalse. Think of it as a tiny fork in the road that must fit on one line.
const score = 91;
const badge = score >= 90 ? "honors" : "regular pass";
console.log(`Ada earns: ${badge}`);→ Ada earns: honors.
Use a ternary when both outcomes are short values. If each side needs several steps, wait for the full if / else tools in lesson 4.3. A cramped ternary is harder to read than a longer decision written clearly.
Precedence decides what runs first
Operator precedence is JavaScript's built-in order for evaluating operators when you do not add parentheses. You already saw this with arithmetic: 2 + 3 * 4 multiplies first. Logic has an order too: ! runs before comparisons, comparisons run before &&, and && runs before ||.
const isWeekend = true;
const choresDone = false;
const hasTournament = false;
const canPlayNow = isWeekend || hasTournament && choresDone;
const clearerCanPlayNow = isWeekend || (hasTournament && choresDone);
const differentQuestion = (isWeekend || hasTournament) && choresDone;
console.log(canPlayNow);
console.log(clearerCanPlayNow);
console.log(differentQuestion);→ true, true, false. Moving the parentheses changed the question.
You do not need to memorize the whole precedence table. Write the parentheses that make the decision readable. Future you is also a beginner when reading tired code at 11 p.m.
You now have the raw ingredients for decisions: comparisons, logic, defaults, and value choices. Next, equality gets its own microscope, because === is the operator you will use every day and JavaScript's older equality rules are famous for surprising beginners.
Checkpoint
Answer all three to mark this lesson complete