Programs constantly need to make decisions: show this message if the user is logged in, apply a discount if the cart total is high enough, pick a greeting based on the time of day. Conditionals are how JavaScript expresses “do this, but only when that’s true.”
if, else if, and elseThe if statement runs a block of code only when its condition evaluates to
a truthy value:
const hour = 14;
if (hour < 12) {
console.log("Good morning!");
} else if (hour < 18) {
console.log("Good afternoon!");
} else {
console.log("Good evening!");
}
// "Good afternoon!"
Breaking down the syntax:
if (condition) — checks the condition; if it’s truthy, the block
that follows runs.else if (condition) — an additional check, only evaluated if every
condition above it was falsy. You can chain as many of these as you
need.else — the fallback block that runs if none of the conditions above
matched. It’s optional — you can have an if with no else at all.Any expression that produces true or false — typically built with the
comparison and logical operators from the Operators lesson — can be used as
a condition.
if/elseWhen a decision boils down to picking one of two values, the ternary
operator (condition ? valueIfTrue : valueIfFalse) expresses it in a single
expression — handy for assigning a variable or building a string:
const age = 20;
const status = age >= 18 ? "adult" : "minor";
console.log(`You are an ${status}.`);
It reads almost like a sentence: “if age >= 18, use "adult", otherwise
use "minor".” Reach for it when both branches are short, simple values —
once the logic gets more involved, a regular if/else is easier to read.
switch — choosing among several known valuesWhen you’re comparing one value against several specific possibilities,
switch can be clearer than a long else if chain:
const day = "Tuesday";
switch (day) {
case "Saturday":
case "Sunday":
console.log("It's the weekend!");
break;
case "Monday":
console.log("Back to it.");
break;
default:
console.log("Just another weekday.");
}
// "Just another weekday."
Each case checks the switched value with strict equality (===). The
break keyword stops the switch from continuing on to the next case, and
default runs when nothing else matched. Stacking cases without a break
between them — like "Saturday" and "Sunday" above — lets them share the
same code.
&& and ||You’ll sometimes see logical operators used to run code conditionally
without a full if statement — most often to render something only when a
value is present:
const errorMessage = "Something went wrong";
errorMessage && console.log(errorMessage); // logs only if errorMessage is truthy
This leans on the short-circuiting behavior covered in the Operators lesson:
&& only evaluates its right-hand side when the left-hand side is truthy.
It’s concise, but an explicit if is usually easier to read for anything
beyond a single simple expression.
Older code — and code translated directly from “if this, then that” thinking — often nests conditionals several levels deep:
function getDiscount(user) {
if (user) {
if (user.isMember) {
if (user.yearsActive > 5) {
return 0.2;
} else {
return 0.1;
}
} else {
return 0;
}
} else {
return 0;
}
}
Each layer of nesting adds more for the reader to track, and the important logic ends up buried in the middle. Modern style favors early returns — handling the simple or invalid cases first and returning immediately, so the rest of the function can assume those cases are already out of the way:
function getDiscount(user) {
if (!user) return 0;
if (!user.isMember) return 0;
if (user.yearsActive > 5) return 0.2;
return 0.1;
}
Same result, far less to hold in your head at once — each line reads as its
own simple rule rather than a layer of an ever-deepening tree. You’ll also
sometimes see old switch statements that forget a break, letting
execution accidentally “fall through” into the next case — a classic bug
that’s worth watching for when reading legacy code.