Chapter 6 — == 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.