#003: The Truth Seekers – Comparisons & Equality in JavaScript ✅❓



This content originally appeared on DEV Community and was authored by Harshit Savani

Hey Dev.to crew! Harshit back on the learning journey! If you’ve been following along, we’ve navigated the realms of Variables & Data Types and bravely explored Type Conversion & Operations. We’ve seen how flexible (and sometimes sneaky) JavaScript can be when handling different kinds of data.

Today, we’re diving into a core pillar of programming: Comparisons and Equality. This is how your code makes decisions, chooses paths, and powers complex logic. Sounds simple, right? Well, JavaScript’s comparison rules, especially with different data types, are packed with famous gotchas that can trip up even seasoned developers. Buckle up for some eyebrow-raising moments! 🤯

The Basics: Relational Operators 🔍

Relational operators let us compare two values to determine their relationship, always returning a boolean (true or false). These are your go-to tools for checking “bigger,” “smaller,” or “equal” in a numeric sense.

  • > (Greater than)
  • < (Less than)
  • >= (Greater than or equal to)
  • <= (Less than or equal to)

When comparing numbers, it’s straightforward:

console.log(10 > 5);   // → true
console.log(5 < 10);   // → true
console.log(10 >= 10); // → true
console.log(5 <= 4);   // → false

Use these when comparing sizes, quantities, or rankings—like scores, prices, or ages.

The Implicit Conversion Quandary

Here’s where JavaScript’s flexibility shines (or sneaks up on you). When you compare values of different data types using relational operators (>, <, >=, <=), JavaScript often converts them to numbers behind the scenes to make the comparison possible. Let’s unpack some examples:

Example 1: "2" > 1

console.log("2" > 1); // → true

What’s Happening? JavaScript sees a string ("2") and a number (1). It implicitly converts the string "2" to the number 2, so the comparison becomes 2 > 1, which is true.

Example 2: "2" > true

console.log("2" > true); // → true

What’s Happening? This is a double conversion trick:

  • The string "2" is converted to the number 2.
  • The boolean true is converted to the number 1 (remember from our last blog: Number(true) is 1).
  • The comparison becomes 2 > 1, which evaluates to true.

Tip: Be cautious with mixed-type comparisons—JavaScript’s automatic conversions can lead to unexpected results if you’re not paying attention!

The Equality Checkers: Loose vs. Strict ⚖

Equality comparisons are where JavaScript’s quirks really shine. Choosing between loose equality (==) and strict equality (===) can make or break your code. Let’s dive into the differences.

Loose Equality Operator (==) – The Forgiving Friend

The == operator checks for value equality but performs type coercion (implicit conversion) if the operands are different types. It tries to convert them to a common type before comparing, which can lead to surprising results.

console.log(5 == "5");         // → true (String "5" converted to Number 5)
console.log(0 == false);       // → true (false converted to Number 0)
console.log("" == 0);          // → true (Empty string "" converted to Number 0)
console.log(null == undefined); // → true (A special rule: they’re loosely equal!)

Why This Happens? The == operator is too forgiving, bending over backwards to make values comparable, which can hide bugs.

Strict Equality Operator (===) – The Uncompromising Judge

The === operator checks for both value and type equality. It never performs type coercion. If the types differ, it returns false immediately—making it predictable and safer.

console.log(5 === "5");         // → false (Different types: Number vs. String)
console.log(0 === false);       // → false (Different types: Number vs. Boolean)
console.log("" === 0);          // → false (Different types: String vs. Number)
console.log(null === undefined); // → false (Different types: null vs. undefined)

Golden Rule: Always prefer === over ==. It avoids unexpected type coercion and makes your code more reliable.

The Head-Scratchers: null and undefined in Comparisons 🤯

Here’s where JavaScript gets really quirky. The behavior of null and undefined in comparisons can confuse even experienced developers. Let’s break down these classic Aha! Moments.

Case 1: null in Comparisons

console.log("null > 0:", null > 0);   // → false
console.log("null == 0:", null == 0); // → false
console.log("null >= 0:", null >= 0); // → true

Why This Happens?

  • Relational Comparisons (>, >=): When null is involved in relational comparisons (>, <, >=, <=), it gets implicitly converted to a number 0.
    • So, null > 0 becomes 0 > 0, which is false.
    • And null >= 0 becomes 0 >= 0, which is true.

✨ Aha! Moment: null == 0 is false!

  • Despite null being converted to 0 in relational comparisons, null is not loosely equal to 0.
  • The specification explicitly states that null and undefined are special cases for == and they are only loosely equal to each other, but not to 0 (or any other number, or false). This prevents null from being confused with other “falsy” values like 0 or false in loose equality. It’s designed to maintain a distinction.

In Summary: null is treated as 0 for numeric comparisons (<, >, <=, >=), but not for == equality checks with numbers.

Case 2: undefined in Comparisons

console.log("undefined == 0:", undefined == 0); // → false
console.log("undefined >= 0:", undefined >= 0); // → false
console.log("undefined <= 0:", undefined <= 0); // → false

Why This Happens?

  • Relational Comparisons: When undefined is used in relational operators (>, <, >=, <=), it converts to NaN (Not-a-Number). Any comparison involving NaN (except NaN != NaN) returns false.
    • undefined > 0 becomes NaN > 0false.
    • undefined >= 0 becomes NaN >= 0false.
    • undefined <= 0 becomes NaN <= 0false.
  • Loose Equality (==): undefined is only loosely equal to null (and itself), not to 0, false, or any other value.

Key Takeaway: undefined is strict—outside its special bond with null, it yields NaN in relational comparisons, making them false.

Case 3: undefined == null – The Special Bond

console.log("undefined == null:", undefined == null); // → true

Why This Happens? JavaScript’s specification defines null and undefined as loosely equal (==) to each other (and themselves). This makes sense, as both represent the absence of a meaningful value.

Case 4: Strict Equality with Type Mismatch

console.log('"1" === 1:', "1" === 1); // → false

Why This Happens? The === operator is strict—it checks types first. Since "1" is a string and 1 is a number, it returns false without comparing values. This predictability is why === is your best friend.

Logical Operators: The Decision Makers 🧠

Logical operators combine boolean values or expressions to produce a single boolean result, powering your code’s decision-making logic.

  • && (Logical AND): Returns true if both operands are true.
console.log(true && true);   // → true
console.log(true && false);  // → false
  • || (Logical OR): Returns true if at least one operand is true.
console.log(true || false);  // → true
console.log(false || false); // → false
  • ! (Logical NOT): Flips the boolean value of its operand.
console.log(!true);  // → false
console.log(!false); // → true

Pro Tip: The !! (double NOT) trick is a quick way to convert any value to its boolean equivalent, just like Boolean(myValue).

console.log(!!"hello"); // → true
console.log(!!0);       // → false

Use these in conditionals, validations, or any logic that depends on combining or flipping boolean values.

Conclusion: Master Your Comparisons, Master Your Logic! 🚀

Understanding JavaScript’s comparison and equality rules is crucial for writing reliable code. The loose equality operator (==) can hide tricky implicit conversions, especially with null and undefined. By favoring === and grasping the quirky behaviors of null and undefined, you’ll dodge bugs and write cleaner, more predictable JavaScript.

Next up, we’ll dive into the world of Strings! Get ready for template literals, string objects, and powerful methods to manipulate text. It’s going to be a string-tastic adventure!

What’s a JavaScript comparison or equality quirk that baffled you when you first encountered it? Share your Aha! Moments or head-scratchers in the comments below! 👇

Over & Out!


This content originally appeared on DEV Community and was authored by Harshit Savani