Q1What does console.log("0" === 0); print?
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 !=.
=== 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.
== 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
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.
&& 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
}
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 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.
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).
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.
Knowledge Check
Answer each question one by one.
Q2Which of these is not falsy?
Q3What does console.log(0 || 100); print?