The `==` Trap and Type Coercion in JavaScript
Why is `"" == 0` true? Why is `[] == false` true? Yet why is `NaN == NaN` false? We break down JavaScript's most confusing mechanism—type coercion—and the only foolproof way to escape the mess.

Picture three simple lines of code: Is an empty string equal to zero ("" == 0)? Is an empty array equal to false ([] == false)? And is NaN equal to itself (NaN == NaN)?
When you ask JavaScript these questions using the == (loose equality) operator, the first two return true, while the last one returns false. To make things weirder, even though an empty string equals zero, the string zero ("0") is not equal to an empty string (""). What about null == 0? False. But if you check null >= 0, the result is true.
At first glance, these results might look completely arbitrary and broken, but nothing here is actually random. Every single one follows a documented rule.
Algorithma and Type Coercion
The engine behind all these quirks is Type Coercion. When you compare two values with == and their types differ, JavaScript converts them under the hood to bring them to a common type.
Take [] == false, for example:
falseis converted to a number first, becoming0. ([] == 0)- The empty array (
[]) is converted to a primitive value, which yields an empty string (""). ("" == 0) - The empty string is then coerced into a number, becoming
0. - Finally, the comparison runs
0 == 0, which evaluates to true.
The sole exception to standard numeric coercion is null. When using loose equality (==), null is only ever equal to undefined; it does not get converted into a number. Relational operators like >= (greater than or equal to), however, make no such exception and coerce null into zero. That's why null == 0 is false, but null >= 0 is true!
The Rule and the Fix
You don't have to memorize every conversion step and edge case. The fix comes down to a single habit and one golden rule: always use triple equals (===).
The triple equals (===) operator checks for Strict Equality. It never coerces types. If the types on either side don't match, it immediately returns false without running any conversions.
There is only one practical exception: when you deliberately want to check for both null and undefined at the same time, writing deger == null is fine. Everywhere else, sticking to === will spare you this headache.
Wrap-Up
If you want to put an end to "Why did it behave like that?" debates on your team, turn on the ESLint eqeqeq rule in your project. That way, you'll wipe out accidental loose equality checks across your codebase once and for all.

