Understanding JavaScript’s ==
vs ===
: Why Strict Equality Wins
JavaScript has two equality operators: ==
(loose equality) and ===
(strict equality). While they might seem similar at first glance, their behavior can be wildly different.
Why Is ==
So Unpredictable?
The ==
operator doesn’t just check if two values are the same—it tries to convert them to a common type before comparing. This leads to some unexpected and, frankly, weird results.
console.log("" == 0); // true
Yes, an empty string and the number zero are considered equal! But it doesn’t stop there:
console.log("0" == false); // true
The Madness of Type Coercion
Things get even crazier when working with arrays:
console.log([1] == true); // true
console.log([] == false); // true
console.log([[]] == false); // true
console.log([0] == false); // true
And even weirder with strings:
console.log([1,2,3] == "1,2,3"); // true
console.log("rnt" == 0); // true
When Equal Is Not Equal
Here’s a mind-bending example:
let A = ""; // empty string
let B = 0; // zero
let C = "0"; // zero as a string
console.log(A == B); // true
console.log(B == C); // true
console.log(A == C); // false (WHAT?!)
This means:
(A == B) && (B == C) // true
(A == C) // false
How is this even possible? It’s because ==
does implicit type conversion, sometimes in ways that defy intuition.
The Chaos of ==
With Objects
When objects are involved, things get even messier. JavaScript attempts to convert objects into primitive values before comparing them. If ==
were a function, it would need a ton of special handling for different cases, something like this:
function isEqual(x, y) {
if (typeof y === typeof x) return y === x;
// Treat null and undefined as equal
if ((y === undefined || y === null) && (x === undefined || x === null))
return true;
// Convert functions to strings if compared with a string
if (typeof y === "function" || typeof x === "function") {
return typeof x === "string" ? x === y.toString() : x.toString() === y;
}
// Convert objects to primitive values
if (typeof x === "object") x = toPrimitive(x);
if (typeof y === "object") y = toPrimitive(y);
if (typeof y === typeof x) return y === x;
// Convert to numbers
if (typeof x !== "number") x = +x;
if (typeof y !== "number") y = +y;
return x === y;
}
function toPrimitive(obj) {
var value = obj.valueOf();
return obj !== value ? value : obj.toString();
}
The Takeaway: Use ===
The ===
operator avoids all this madness. It strictly compares both value and type, preventing unexpected type coercion.
console.log("" === 0); // false
console.log("0" === false); // false
console.log([] === false); // false
console.log("rnt" === 0); // false
Using ===
makes your code more predictable and reduces the risk of weird bugs caused by JavaScript’s automatic type conversion.
Final Thought
JavaScript’s loose equality (==
) might seem convenient at times, but it’s full of surprises. Instead of dealing with unexpected behavior, make your life easier: use ===
.
The End.