Chapter 09 โ == vs === (Equality)
๐ Definition
==performs loose equality with type coercion.===performs strict equality โ no coercion, types must match.
๐ Explanation
== tries to make types match before comparing. The rules are notoriously inconsistent, which is why most teams ban == outright (ESLint eqeqeq).
Coercion Rules (==)
- If types match โ behave like
===. null == undefinedโtrue(special rule).- Number vs string โ string is converted to number.
- Boolean โ converted to number (
true โ 1,false โ 0). - Object vs primitive โ object is converted via
valueOf/toString.
๐ป Code Example โ Surprising Coercions
0 == "0"; // true (string โ number 0)
0 == ""; // true (empty string โ 0)
0 == false; // true (false โ 0)
"" == false; // true (both โ 0)
null == undefined; // true (special rule)
null == 0; // false (special exception)
[] == false; // true ([] โ "" โ 0; false โ 0)
[1] == 1; // true ([1] โ "1" โ 1)
[1, 2] == "1,2"; // true
NaN == NaN; // false (NaN never equals anything)
NaN === NaN; // false๐ป Code Example โ Strict Equality
0 === "0"; // false (different types)
0 === false; // false
null === undefined; // false
NaN === NaN; // false
1 === 1; // true
"a" === "a"; // true๐ป Code Example โ Object Equality
const a = { x: 1 };
const b = { x: 1 };
const c = a;
a === b; // false โ different references
a === c; // true โ same reference
// Deep equality requires a helper:
JSON.stringify(a) === JSON.stringify(b); // true (works for simple shapes)๐ป Code Example โ Checking for NaN
// Wrong:
x === NaN; // always false
// Right:
Number.isNaN(x); // ES6, type-safe
isNaN("abc"); // true (legacy โ coerces first)
Number.isNaN("abc"); // false (no coercion)๐ป Code Example โ Object.is
Object.is(NaN, NaN); // true
Object.is(+0, -0); // false (=== returns true)
Object.is(1, 1); // trueObject.is is the same as === except for NaN and signed zeros.
๐ป Code Example โ Safe Null Checks
// Loose check covers both null and undefined
if (value == null) {
// matches null OR undefined
}
// Strict equivalent
if (value === null || value === undefined) {}
// Modern (preferred)
if (value ?? false) {} // ?? treats only null/undefined as empty๐ Real-World Impact
- Always use
===unless you specifically wantvalue == nullto catch bothnullandundefined. - Add
"eqeqeq": "error"to ESLint config. - For deep equality, use
lodash.isEqualor a library; never roll your own without testing edge cases.
๐ฏ Likely Interview Questions
- Difference between
==and===? - Why is
[] == falsetrue? โ[]converts viatoStringโ""โ number0.falseโ0. Both equal. - How do you check for
NaN? โNumber.isNaN(x). - How do you compare two objects for value equality? โ
JSON.stringify(limited),lodash.isEqual, or a custom deep-equals.