AniUI Academy

Making Decisions

if, else, comparisons, truthy and falsy — plus the difference between === and ==, and why ?? saves you when a value is legitimately 0 or empty.

10 min read

Code that always does the same thing is not much use. The moment you want to show a discount to some people, or a warning only when something is wrong, you need a way to ask a question and act on the answer.

if, else if, else

The shape is always the same: a question in brackets, and a block that runs only if the answer is true.

const minutes = 12;
 
if (minutes > 10) {
  console.log("Long lesson");
}

Add else for the other case, and else if for anything in between:

if (minutes > 15) {
  console.log("Long");
} else if (minutes > 8) {
  console.log("Medium");
} else {
  console.log("Short");
}
// "Medium"

Read that as a list checked top to bottom. The first condition that is true wins, its block runs, and everything below it is skipped entirely. This is why order matters more than beginners expect. Flip the first two conditions and a 12-minute lesson would report "Long", because minutes > 8 would match first and nothing after it would ever be reached. Put the narrow cases before the broad ones.

Comparing values

5 > 3;   // true  — greater than
5 < 3;   // false — less than
5 >= 5;  // true  — greater than or equal
5 <= 4;  // false
5 === 5; // true  — equal
5 !== 3; // true  — not equal

Each of these produces a boolean, a value that is only ever true or false. You can store one in a variable like anything else:

const isLong = minutes > 10;

Always use ===, never ==

JavaScript has two equality operators, and one of them is a trap.

=== compares value and type. If the types differ, the answer is false and that is the end of it.

== tries to be helpful. When the types differ it converts one side before comparing, and the conversion rules are a tangle:

"0" == 0;     // true  — the string became a number
"" == 0;      // true
null == undefined; // true
"1" == true;  // true

None of that is useful, and all of it hides bugs. Compare with ===:

"0" === 0;   // false
"" === 0;    // false

Use === and !== every time. The one exception you will meet in real code is value == null, a compact way of asking "is this null or undefined", but even that is clearer written out in full.

Truthy and falsy

Every value in JavaScript can be treated as a question on its own, without any comparison. Most values count as true. Exactly eight count as false, and this is the complete list:

  • false
  • 0 and -0
  • 0n (a zero BigInt, a rarely used number type for very large whole numbers)
  • "" (an empty string)
  • null
  • undefined
  • NaN

Everything else is truthy. That includes "0", "false", an empty array [] and an empty object {}, which surprises people.

Memorising that short list pays off, because real code leans on it constantly:

const name = "";
 
if (name) {
  console.log("Hello, " + name);
} else {
  console.log("Please tell us your name");
}

That reads as "if there is a name". No comparison, no === "". Same idea for checking that something exists before using it:

if (user) {
  console.log(user.email);
}

and, or, not

Three operators combine or flip conditions.

const minutes = 12;
const published = true;
 
minutes > 10 && published; // true  — both must be true
minutes > 20 || published; // true  — at least one must be true
!published;                // false — flips it

In practice they read almost like English:

if (user && user.isSubscribed) {
  console.log("Show the full lesson");
}
 
if (!user) {
  console.log("Ask them to sign in");
}

&& stops as soon as it finds something falsy, and || stops as soon as it finds something truthy. That is why the first example is safe: if user is undefined, JavaScript never gets as far as reading user.isSubscribed, which would otherwise crash.

The ternary operator

When a decision picks between two values, an if block is a lot of lines for very little. The ternary does it in one — condition, then ?, then the value for true, then :, then the value for false.

const label = minutes > 10 ? "Long" : "Short";

Use it for simple either-or choices, especially inside text:

console.log(`This is a ${minutes > 10 ? "long" : "short"} lesson`);

Do not nest them. A ternary inside a ternary is technically legal and genuinely hard to read; that is where a normal if earns its keep.

switch, for long chains

When you are checking one value against many fixed options, a switch says so more plainly than five else if lines:

switch (level) {
  case "beginner":
    console.log("Start here");
    break;
  case "intermediate":
    console.log("Keep going");
    break;
  default:
    console.log("Unknown level");
}

break stops the switch. Leave it out and JavaScript keeps running the cases below, which is occasionally useful and usually a bug. Reach for switch only when every branch compares the same variable to a fixed value; anything with ranges or combined conditions belongs in an if chain.

?? for defaults that respect 0

|| is often used to supply a fallback, and it works right up until the real value is falsy:

const perPage = settings.perPage || 10;

If someone deliberately set perPage to 0, that 0 is falsy and gets thrown away. Same problem with an empty string that the user meant to leave empty.

??, the nullish coalescing operator, only falls back when the left side is null or undefined. Nothing else:

0 || 10;  // 10 — probably wrong
0 ?? 10;  // 0  — the value the user chose
 
null ?? 10; // 10 — the genuine "nothing here" case

Use ?? whenever 0, "" or false are legitimate values, which is most of the time.

Try it yourself

Change minutesWatched to 0 and then to null, and watch the last two lines disagree.

Try it yourself
Loading playground...

What to remember

  • An if chain stops at the first match, so put specific conditions before general ones.
  • Use === always. == converts types behind your back.
  • Eight values are falsy: false, 0, -0, 0n, "", null, undefined, NaN.
  • && and || stop early, which is what makes user && user.email safe.
  • ?? falls back only for null and undefined, so it protects a real 0.

Check yourself

4 questions · pass 3/4 to unlock Repeating Work

up to 50
  1. 1.What does "0" == 0 evaluate to, and why?

  2. 2.Which of these values is truthy?

  3. 3.A user leaves a setting at 0. What does const perPage = setting || 10; give you?

  4. 4.In a chain of if and else if, why does the order of the conditions matter?

4 left to answer