Understand == vs === and why they behave differently. Learn Object.is(), the NaN edge case, and when loose equality is actually useful.
Why: == coerces types before comparing. It can produce surprising results. Prefer === in almost all cases.
// Type coercion happens
console.log(1 == '1'); // true — string coerced to number
console.log(0 == false); // true — false → 0
console.log('' == false); // true
console.log(null == undefined); // true — special rule
console.log(null == 0); // false — null only == undefined
// Objects compare by reference, not value
const a = [1, 2];
const b = [1, 2];
console.log(a == b); // false — different references
// When == is useful: null-check shorthand
const val = null;
if (val == null) console.log('val is null or undefined');Why: === compares value AND type with no coercion. Object.is() is like === but correctly handles NaN and distinguishes +0 from -0.
// === never coerces
console.log(1 === '1'); // false
console.log(0 === false); // false
console.log(null === undefined); // false
// NaN edge case with ===
console.log(NaN === NaN); // false — NaN ≠ itself
console.log(Number.isNaN(NaN)); // true — use this instead
console.log(Number.isNaN('abc')); // false (stricter than global isNaN)
// Object.is — handles two edge cases === misses
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(+0, -0)); // false
console.log(+0 === -0); // true (=== gets this wrong)
// Use === by default
console.log(5 === 5); // true
console.log(5 === '5'); // false