JavaScript lesson 5 of 9
JavaScript Conditionals: if, else if, and else
Learn how JavaScript makes decisions with if, else if, and else, the difference between === and ==, truthiness, and the ternary operator.
Published · Every example on this page was run before it was published.
Every program you have written so far runs straight through from the first line to the last, doing the exact same thing every time. Real programs are not like that. A login screen shows a welcome message or an error message. A shopping cart applies a discount only when the total is big enough. A game ends only when your health reaches zero. To write programs like those you need a way to say "run this part only when something is true," and in JavaScript that tool is the conditional statement.
What a Condition Is
A condition is any expression that JavaScript can boil down to one of two values: true or false.
Those two values are a real JavaScript type, boolean, just like number and string are. You can
store them in variables, log them, and combine them.
Think of a condition as a yes-or-no question asked about your data. A bouncer at a club door asks one
question — "is this person eighteen or older?" — and the answer is always yes or no, never "maybe." Depending
on the answer, the bouncer takes one of two actions. JavaScript works the same way: it evaluates the
question, gets true or false, and picks a path.
The most common way to build a condition is with a comparison operator, which compares two values and produces a boolean:
| Operator | Question it asks |
| --- | --- |
| === | Are these two values equal, and the same type? |
| !== | Are these two values different, in value or type? |
| > | Is the left value greater than the right? |
| < | Is the left value less than the right? |
| >= | Is the left value greater than or equal to the right? |
| <= | Is the left value less than or equal to the right? |
Comparisons work on their own, outside of any if statement. You can log them directly to see the
boolean that comes out:
const age = 20;
console.log(age > 18);
console.log(age === 20);
console.log(age !== 20);
console.log(3 + 4 >= 10);
console.log("cat" === "Cat");true
true
false
false
falseThat last line matters: string comparison in JavaScript is case-sensitive, so "cat" and "Cat" are
different values. Note also that JavaScript evaluates the arithmetic 3 + 4 first and only then
compares the result 7 against 10, which is why that line is false.
Writing if, else if, and else
An if statement takes a condition and a block of code wrapped in curly braces. If the condition is
true, the block runs. If it is false, JavaScript skips the whole block and carries on with the rest
of the program.
const temperature = 31;
if (temperature > 28) {
console.log("It is hot today.");
console.log("Remember to drink water.");
}
console.log("Have a good day.");It is hot today.
Remember to drink water.
Have a good day.Notice the shape of that code. The line starting with if is followed by the condition in
parentheses, then an opening curly brace. Everything up to the matching closing brace belongs to the
if. Unlike some languages, indentation here is purely for human readers — JavaScript itself only
cares about the braces. Indenting consistently anyway is a very good habit, because a program whose
indentation does not match its braces is almost unreadable to everyone, including you in six months.
To handle the false case, add an else block. It has no condition of its own — it simply catches
everything the if did not:
const password = "hunter2";
if (password.length >= 8) {
console.log("Password accepted.");
} else {
console.log("Password is too short.");
}Password is too short.The string "hunter2" has seven characters, so password.length >= 8 is false and the else block
runs. Exactly one of the two blocks runs — never both, never neither.
When you have more than two possible outcomes, use else if. You can chain as many as you need between
the opening if and an optional closing else:
const score = 83;
let grade;
if (score >= 90) {
grade = "A";
} else if (score >= 80) {
grade = "B";
} else if (score >= 70) {
grade = "C";
} else {
grade = "F";
}
console.log("Your grade is", grade);Your grade is BJavaScript checks the conditions strictly from top to bottom and stops at the first one that is
true. It never looks at the rest, which is why order matters enormously in an else if chain. Here
is the same idea with the conditions written in the wrong order:
const score2 = 95;
if (score2 >= 70) {
console.log("C");
} else if (score2 >= 80) {
console.log("B");
} else if (score2 >= 90) {
console.log("A");
}CA score of 95 really is greater than or equal to 70, so the very first branch wins and the better branches below it are never reached. The fix is to put the most demanding condition first.
=== Versus ==
JavaScript has two different equality operators, and choosing the wrong one is one of the most common
sources of bugs in beginner code. ===, called strict equality, compares both the value and the
type, and never converts one side to match the other. ==, called loose equality, tries to make the
two sides comparable first, converting one or both before comparing.
console.log(5 === 5);
console.log(5 === "5");
console.log(5 == "5");
console.log(null == undefined);
console.log(null === undefined);
console.log(NaN === NaN);true
false
true
true
false
false5 === "5" is false because a number and a string are never the same type, no matter what they look
like. 5 == "5" is true because == converts the string to a number before comparing. null and
undefined are a special case: == treats them as equal to each other and to nothing else, while
=== correctly reports them as different types.
The last line is worth remembering on its own: NaN is defined to be unequal to everything,
including itself. Neither === nor == will ever tell you a value is NaN — you need the dedicated
function Number.isNaN() for that, which you met in the previous lesson.
The coercion rules behind == are not always intuitive, and they can produce results that look
outright inconsistent:
console.log(0 == "");
console.log(0 == "0");
console.log("" == "0");true
true
false0 equals "" and 0 equals "0", and yet "" does not equal "0" — equality that behaves this way
is not something you want to reason about while debugging. The practical rule: use === and !==
by default, always. Reach for == only in the one deliberate case of treating null and undefined
as interchangeable, and even then a direct value === null || value === undefined is often clearer.
Combining Conditions with && || !
Real decisions usually depend on more than one fact. JavaScript gives you three logical operators to
build compound conditions out of simpler ones: && is true only when both sides are true, || is true
when at least one side is true, and ! flips a single boolean to its opposite.
const day = "Saturday";
const weather = "sunny";
if (day === "Saturday" && weather === "sunny") {
console.log("Perfect beach day.");
}
if (day === "Saturday" || day === "Sunday") {
console.log("It is the weekend.");
}
if (weather !== "rainy") {
console.log("No umbrella needed.");
}Perfect beach day.
It is the weekend.
No umbrella needed.&& and || also have an important safety feature called short-circuiting. With &&, if the left
side is already false (or falsy — more on that shortly), JavaScript never even evaluates the right
side, because the overall answer cannot change. That lets you guard a risky operation behind a cheap
check:
const user = null;
if (user && user.name.toUpperCase()) {
console.log("Has a name");
} else {
console.log("No user yet.");
}No user yet.If user is null, reading user.name would normally crash the program with a TypeError, because
null has no properties at all. Since the left side of the && is already falsy, JavaScript never
evaluates user.name.toUpperCase() at all. Put the guard on the left and the thing that needs guarding
on the right.
Truthiness: What JavaScript Treats as False
The condition in an if statement does not have to be an actual boolean. JavaScript will accept any
value and decide for itself whether that value counts as true or false. This behaviour is called
truthiness, and the values that count as false are called falsy.
There are exactly seven falsy values in JavaScript, and it is worth memorising all of them because there are no others:
console.log(Boolean(0));
console.log(Boolean(42));
console.log(Boolean(""));
console.log(Boolean("hi"));
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(NaN));
console.log(Boolean([]));
console.log(Boolean({}));false
true
false
true
false
false
false
true
true0, "", null, undefined, and NaN are falsy (-0 and the rarely-seen BigInt 0n are too, for
completeness). Every non-zero number, every non-empty string, and — this is the one that catches
people coming from other languages — every array and every object is truthy, even an empty one.
[] and {} are both real objects as far as JavaScript's truthiness rules are concerned, and an
object's truthiness never depends on what is inside it.
That last fact has a direct practical consequence: you cannot check whether an array is empty by
putting the array itself in a condition. You have to check its .length:
const cart = [];
if (cart.length) {
console.log(`Your cart has ${cart.length} items.`);
} else {
console.log("Your cart is empty.");
}Your cart is empty.cart.length is 0, which is falsy, so the check works correctly here — but if (cart) on its own
would have been true regardless of how many items were inside, because cart is an array, and every
array is truthy.
The Ternary Operator
Sometimes you only want to choose between two values, not two blocks of code. Writing a four-line
if/else just to set one variable feels heavy, so JavaScript offers a one-line form called the
ternary operator, written condition ? valueIfTrue : valueIfFalse.
let count = 1;
let label = count === 1 ? "item" : "items";
console.log(count, label);
count = 4;
label = count === 1 ? "item" : "items";
console.log(count, label);1 item
4 itemsThe condition before the ? is evaluated first; if it is true the whole expression becomes the
value before the :, and otherwise it becomes the value after. Because it is an expression rather than
a statement, you can use it anywhere a value is allowed — inside a console.log() call, inside a
template literal, or on the right-hand side of an assignment as above.
Keep it for short, simple choices. If either branch needs more than a brief value, or you find yourself
nesting one ternary inside another, go back to a regular if/else; the extra lines buy real
readability.
A Worked Example
This short program reviews a week of temperature readings, labels each one, counts the extremes, and
finishes with a ternary-built summary. It pulls together comparisons, an else if chain, counters, and
the ternary operator.
const readings = [22, 33, -2, 15, 41, 0];
let hotDays = 0;
let coldDays = 0;
for (const reading of readings) {
let status;
if (reading >= 30) {
status = "hot";
hotDays++;
} else if (reading <= 0) {
status = "cold";
coldDays++;
} else {
status = "mild";
}
console.log(reading, "->", status);
}
console.log("Hot days:", hotDays);
console.log("Cold days:", coldDays);
const alert = hotDays >= 2 ? "heat warning" : "no warning";
console.log("Status:", alert);22 -> mild
33 -> hot
-2 -> cold
15 -> mild
41 -> hot
0 -> cold
Hot days: 2
Cold days: 2
Status: heat warningHere is what each part does. hotDays and coldDays are two counter variables, declared with
let because they need to change, and started at zero. The for...of loop — covered properly in a
later lesson — simply hands reading one value from readings at a time.
Inside the loop sits an else if chain. JavaScript first asks whether the reading is at least 30. If
so, it labels the day "hot" and increments hotDays. Only if that first question is false does it
ask the second one, whether the reading is zero or below. If both fail, the else block labels the day
"mild". Exactly one of the three branches runs for each reading, so no day is ever counted twice —
notice that 0 is correctly labelled "cold" because the condition asks reading <= 0 explicitly,
rather than relying on the truthiness of reading, which would have treated 0 as falsy for the wrong
reason.
After the loop finishes, the two console.log calls report the totals, and the ternary operator picks
one of two strings based on hotDays. Since two days reached 30 degrees or more, hotDays >= 2 is
true and alert becomes "heat warning".
Common Mistakes
Writing = instead of === inside a condition
let x = 5;
if (x = 10) {
console.log("x is now", x);
}x is now 10Unlike a language that refuses to compile this, JavaScript accepts x = 10 inside the parentheses
without complaint. It is a perfectly legal assignment expression: it sets x to 10 and then
evaluates to 10, which is truthy, so the block runs — and x has been silently changed as a side
effect of a line that looked like a comparison. Read === out loud as "is equal to" and a bare = as
"gets," and always double-check an if condition that contains a single equals sign.
Letting ! bind tighter than you expect
const weather = "sunny";
if (!weather === "rainy") {
console.log("No umbrella needed.");
} else {
console.log("Check the forecast.");
}Check the forecast.This looks like it should ask "is the weather not rainy," but ! binds more tightly than ===, so
JavaScript evaluates !weather first. weather is the non-empty string "sunny", which is truthy, so
!weather is false — and false === "rainy" is false, because a boolean is never equal to a
string. The else branch runs, printing the wrong message for a sunny day. Parenthesise explicitly, or
better, use !== directly:
const weather = "sunny";
console.log(!(weather === "rainy"));
console.log(weather !== "rainy");true
trueChecking an array or object itself instead of its contents
const cart = [];
if (cart) {
console.log("Cart exists, so...checkout?");
} else {
console.log("No cart.");
}Cart exists, so...checkout?cart is an array, and every array is truthy regardless of what is inside it — even this empty one. If
what you actually want to know is whether the array has anything in it, check cart.length instead of
cart itself, exactly as the truthiness section above demonstrated.
Next Steps
Try the linked practice problem, balanced-parentheses. It asks you to scan through a string and
decide whether every opening bracket has a matching closing one, which means making a decision about
every single character — an if for an opener, an else if for a closer, and a careful check for the
mismatch case. It is an excellent exercise in getting an else if chain in the right order.
Before that, open the JavaScript playground and experiment. Change the
values in the grading chain and confirm you can predict the branch that runs. Log Boolean() of a few
odd values, such as Boolean(" ") and Boolean("0"), and see whether the results surprise you. Getting
a feel for which conditions are true is the fastest route to writing them confidently.
When you want a harder one
Interview-style problems graded against hidden tests — a big step up from the exercises. Come back to these when the ideas in this lesson feel comfortable rather than new.