Learn by reading through in order

Booleans and Comparison — the Difference Between == and ===

Learn how === and == differ, how to build conditions with comparison and logical operators, and the 6 falsy values.

Have they met the free-shipping threshold? Are they logged in? Is anything left in stock? Switching what's on screen always starts with checking whether a condition is true.

This article covers the difference between === and == for checking equality, comparison and logical operators for building conditions, and the 6 falsy values (values that act like false inside a condition) that JavaScript treats as false.

Checking Equality — the Difference Between === and ==

Picture matching a value typed into an input field against one the system already has stored. Even if they look the same — both 0 — the one from the input field is the string "0", while the stored one is the number 0.

JavaScript has two operators for deciding whether to treat these two as "equal."

=== returns true only when both the type and the value match. If the types differ, that's an immediate false.

The other one, ==, converts one side to match the other's type first, then compares the values. "0" and 0 are false with === but true with ==. There are two "not equal" operators too: !== and !=.

=== and == Follow Different Steps
"0" === 0Types differ,stops therefalse"0" == 0Converts, thencompares valuestrue0 === 0Same type,same valuetrue
=== returns false immediately if the types differ; == converts types to match first, then compares.

The conversion here means reading the string "0" as the number 0. The problem is that == slips this conversion in before comparing.

Since it compares the converted results, the check doesn't always match what you actually wrote. Values that look completely different, like the empty string "" and 0, can end up true.

Each combination of types converts in a fixed direction, but rather than memorizing those rules, use === so that no conversion happens at all — the results are far easier to follow. In new code, use === and !==, and convert values to the same type before comparing them. The next article, on type conversion, covers which direction the conversion runs and how to match up types yourself.

== Slips a Conversion In Before Comparing
"" == 0Conversionslips intrue"0" == 0Conversionslips intrue"" === 0No conversionfalse
== compares the converted results, so it doesn't always match what you wrote. === skips the conversion. Which direction it converts is covered in the next article.
const typedQuantity = "3";   // quantity typed into an input field (string)
const savedQuantity = 3;     // stored quantity (number)

console.log(typedQuantity === savedQuantity);  // false  types differ
console.log(typedQuantity == savedQuantity);   // true   converts to match, then compares

// Same types compare cleanly even with ===
console.log(savedQuantity === 3);   // true
console.log(savedQuantity !== 3);   // false  the negation of ===

console.log("" == 0);         // true   an empty string converts to 0 too
console.log("100" === 100);   // false  === never converts

Match a stock count typed into an input field against the system's stored count. The string typedStock and the number storedStock are already declared.

① Print the result of comparing the two with ==.

② Print the result of comparing the same two with ===.

③ Check whether the same two are not equal in type or value, and print the result.

(If it runs correctly, an explanation will appear.)

JavaScript / TypeScript Editor

Run code to see output

Building Conditions — Comparison and Logical Operators

A real check needs more than just "are these equal." You'll need conditions like "is the total 5000 or more" or "logged in and also an admin."

Comparison operators (symbols that check the relationship between two values — === from earlier in this article is one of them) compare magnitude, and logical operators (symbols that combine booleans) chain multiple conditions together.

The 4 that compare magnitude are > < >= <=, and their result is always true or false.

There are 3 logical operators. && is true only when both sides are true, || is true when either side is true, and ! swaps true and false.

The 3 Logical Operators
&&Only whenboth are truetrue||When eitheris truetrue!Swaps trueand falseOpposite value
&& narrows a condition, || widens it, and ! flips the result.

The condition you build gets passed to an if statement (a construct that runs the block after it only when the parenthesized condition is true). Whatever should run when the condition is false goes in the block after else.

We're only using if here to check what a condition evaluates to — chaining else if and branching with switch come up in the conditionals article in the syntax category.

const cartTotal = 4800;    // cart total
const hasCoupon = true;    // whether they have a coupon
const isMember = false;    // whether they're a member

console.log(cartTotal >= 5000);   // false  hasn't reached 5000
console.log(cartTotal < 5000);    // true

console.log(hasCoupon && isMember);   // false  not a member
console.log(hasCoupon || isMember);   // true   has a coupon, though
console.log(!isMember);               // true   flips false

if (cartTotal >= 5000) {
  console.log("Free shipping");   // runs only when the condition is true
} else {
  console.log(`${5000 - cartTotal} more for free shipping`);   // this runs when it's false
}

Switch which menu shows based on login status and an admin flag together. isLoggedIn (whether they're logged in) and isAdmin (whether they're an admin) are already declared.

① Print whether they're logged in and also an admin.

② Print whether they're logged in and not an admin.

③ Print "My Page" only when ②'s condition is true.

JavaScript / TypeScript Editor

Run code to see output

Truthy and Falsy — What if Treats as False

You can put values other than true / false inside an if's parentheses. When you do, JavaScript reads whatever it's given as one or the other.

A value that reads as false is called falsy; everything else is truthy (a value that acts like true inside a condition). There are only 6 falsy values you'll run into in a condition, so once you know those 6, you can treat everything else as truthy.

The 6 are false, the number 0, the empty string "", null (a value deliberately set to mean nothing's there), undefined (a value meaning nothing's been assigned yet), and NaN. When to use null versus undefined is covered in a later article.

In practice you'll mostly run into 0 and "", so those two are worth knowing first. NaN is the one exception — comparing it against itself with === still gives false — so checking for NaN takes a dedicated approach instead.

The 6 Falsy Values
false0""empty stringnullundefinedNaN"0"string zero" "one space-1nonzero numberThe 6 falsy valuesLook falsy, but truthy
The top 2 rows are the complete list of falsy values. Everything else is truthy, including values in the bottom row that look like 0 or empty but aren't.

The tricky ones are the number 0 and an empty string.

When a review count is 0, or a search field is empty (""), passing that value straight to if makes the condition fail. What you meant as "does it have a value" ends up checking "is it nonzero and non-empty" instead.

const reviewCount = 0;    // review count
const searchWord = "";    // text typed into the search field

if (reviewCount) {
  console.log("Has reviews");
}
if (searchWord) {
  console.log("Has a search term");
}
// 0 and an empty string are both falsy, so neither of the above runs

if (reviewCount === 0) {
  console.log("No reviews yet");   // this one runs
}

Spell Out the Condition When 0 Is a Meaningful Value

For values where 0 itself is meaningful — a stock count, a total, an amount — writing if (stock) skips the block precisely when it's 0. Spelling out what you're actually checking, as in stock > 0 or stock === 0, makes the intent clear to the reader too.

Write code that prints stock counts. mugStock, which is out of stock, and bottleStock, which has stock, are already declared.

① Using mugStock directly as the condition, write code that prints a line with the stock count in it, like "Mug: 5 left." This step is about seeing what happens — the correct outcome is that this line does NOT print.

② Using bottleStock the same way as the condition, print the stock count in the same format.

③ Use an if / else on whether mugStock is greater than 0, printing "Mug: X left" if there's stock and "Mug: out of stock" if not.

JavaScript / TypeScript Editor

Run code to see output

Short-Circuit Evaluation — Setting Up a Default with ||

Even a user who registered without typing a display name needs to see something on screen. This kind of "use a default when there's no value" logic can be written in one line with ||.

This works because && and || don't produce a boolean — they return one of the two values on either side, as-is. When you combine true and false values with them, the result still comes out true or false, so it doesn't conflict with what you've learned so far.

|| returns the left value as-is if it's truthy, and never even evaluates the right side. Only when the left is falsy does it return the right value.

&& works the opposite way — if the left is falsy, it returns that left value without evaluating the right. This "don't look at the right side until you need to" behavior is called short-circuit evaluation (skipping evaluation of the right side once the left side alone decides the result).

|| Returns a Value, Not a Boolean
"" || "Guest"Left is falsy→ returns right"Guest""Alice" || "Guest"Left is truthy→ returns left"Alice"0 || 1000 is falsy too→ returns right100
If the left is truthy, it's returned as-is; the right only comes back when the left is falsy. 0 is falsy too, so it gets replaced by the right side.
const nickname = "";   // left blank

// || returns the right side only when the left is falsy
console.log(nickname || "Guest");    // Guest
console.log("Bob" || "Guest");        // Bob  the right side is never evaluated

// && returns the left value if it's falsy, without evaluating the right
console.log(0 && "in stock");   // 0
console.log(5 && "in stock");   // in stock

|| Isn't Enough When You Want to Keep 0 or an Empty String

|| replaces every falsy value with the default, so meaningful falsy values disappear too — a points balance of 0, or a typed "0". To use a default only when the value is null or undefined, use the separate ?? operator instead, covered in article 9.

Apply defaults to a display name and a points balance. guestName (left blank), memberName (already filled in), and memberPoint (a points balance) are already declared.

① Print a display name that falls back to "Guest" when guestName is blank.

② Print the same pattern applied to memberName.

③ Print the same pattern applied to memberPoint with a default of 100.

JavaScript / TypeScript Editor

Run code to see output
QUIZ

Knowledge Check

Answer each question one by one.

Q1What does console.log("0" === 0); print?

Q2Which of these is not falsy?

Q3What does console.log(0 || 100); print?