Types & Coercionhigh

== vs === (Equality)

=== (strict equality) checks value and type without coercion. == (abstract equality) checks value after type coercion if types differ. Almost always use ===.

Memory anchor

=== is a strict bouncer: 'Are you EXACTLY on the list? Same name, same type?' == is the lazy bouncer: 'Eh, close enough — come in.' NaN is the person who doesn't even recognize themselves in a mirror: NaN !== NaN.

Expected depth

The one legitimate use of == is null checking: x == null is true for both null and undefined, which is often exactly what you want when checking for 'no value'. typeof checks don't need === since typeof always returns a string. NaN !== NaN is a spec quirk — use Number.isNaN() to check for NaN (isNaN() coerces first: isNaN('hello') is true). Object equality with === checks reference identity, not structural equality — {a:1} !== {a:1}.

Deep — senior internals

The Abstract Equality Comparison algorithm (spec §7.2.14) is 12 steps of coercion rules. The interesting ones: if one operand is null and the other is undefined, return true. If one is a number and the other is a string, convert string to number. If one is boolean, convert it to number (ToNumber(false)=0, ToNumber(true)=1). If one is an object and the other is a primitive, call ToPrimitive on the object. Object.is() provides SameValueZero semantics: Object.is(NaN, NaN) is true, Object.is(-0, +0) is false — Map/Set use SameValueZero for key comparison.

🎤Interview-ready answer

Use === by default. The one exception: x == null catches both null and undefined in a single check. === checks type and value without coercion; == applies the Abstract Equality Comparison algorithm which has counterintuitive edge cases. For NaN, use Number.isNaN() since NaN !== NaN. For structural equality of objects, implement a deep-equal function or use a library.

Common trap

Number.isNaN(x) and isNaN(x) behave differently: Number.isNaN only returns true for actual NaN values; global isNaN coerces its argument first (isNaN('hello') === true, Number.isNaN('hello') === false). Always prefer Number.isNaN.