Skip to content

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:

JavaScript
const age = 20;

console.log(age > 18);
console.log(age === 20);
console.log(age !== 20);
console.log(3 + 4 >= 10);
console.log("cat" === "Cat");
Output
true
true
false
false
false

That 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.

JavaScript
const temperature = 31;

if (temperature > 28) {
  console.log("It is hot today.");
  console.log("Remember to drink water.");
}

console.log("Have a good day.");
Output
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:

JavaScript
const password = "hunter2";

if (password.length >= 8) {
  console.log("Password accepted.");
} else {
  console.log("Password is too short.");
}
Output
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:

JavaScript
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);
Output
Your grade is B

JavaScript 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:

JavaScript
const score2 = 95;

if (score2 >= 70) {
  console.log("C");
} else if (score2 >= 80) {
  console.log("B");
} else if (score2 >= 90) {
  console.log("A");
}
Output
C

A 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.

JavaScript
console.log(5 === 5);
console.log(5 === "5");
console.log(5 == "5");
console.log(null == undefined);
console.log(null === undefined);
console.log(NaN === NaN);
Output
true
false
true
true
false
false

5 === "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:

JavaScript
console.log(0 == "");
console.log(0 == "0");
console.log("" == "0");
Output
true
true
false

0 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.

JavaScript
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.");
}
Output
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:

JavaScript
const user = null;

if (user && user.name.toUpperCase()) {
  console.log("Has a name");
} else {
  console.log("No user yet.");
}
Output
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:

JavaScript
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({}));
Output
false
true
false
true
false
false
false
true
true

0, "", 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:

JavaScript
const cart = [];

if (cart.length) {
  console.log(`Your cart has ${cart.length} items.`);
} else {
  console.log("Your cart is empty.");
}
Output
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.

JavaScript
let count = 1;
let label = count === 1 ? "item" : "items";
console.log(count, label);

count = 4;
label = count === 1 ? "item" : "items";
console.log(count, label);
Output
1 item
4 items

The 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.

JavaScript
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);
Output
22 -> mild
33 -> hot
-2 -> cold
15 -> mild
41 -> hot
0 -> cold
Hot days: 2
Cold days: 2
Status: heat warning

Here 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

JavaScript
let x = 5;
if (x = 10) {
  console.log("x is now", x);
}
Output
x is now 10

Unlike 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

JavaScript
const weather = "sunny";
if (!weather === "rainy") {
  console.log("No umbrella needed.");
} else {
  console.log("Check the forecast.");
}
Output
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:

JavaScript
const weather = "sunny";
console.log(!(weather === "rainy"));
console.log(weather !== "rainy");
Output
true
true

Checking an array or object itself instead of its contents

JavaScript
const cart = [];

if (cart) {
  console.log("Cart exists, so...checkout?");
} else {
  console.log("No cart.");
}
Output
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.