JavaScript Equality & Type Coercion: == vs === (With Interview Traps)
A deep, interview-ready guide to JavaScript equality: == vs ===, truthy/falsy, ToPrimitive coercion, Object.is, NaN, -0, and common output questions.
Frontend Interview Team
February 08, 2026
Equality questions are common in interviews because they reveal whether you understand:
- type coercion
- edge cases (
NaN,-0) - how JS converts values
If you learn a few rules, you can answer almost any trick question.
30‑second interview answer
=== compares without coercion; == coerces types, which creates tricky cases. Coercion happens via ToPrimitive/ToNumber rules, so memorize the common traps ('' == 0, null == undefined, arrays/objects). Object.is differs from === mainly for NaN and -0.
Key points
- Prefer
===. null == undefinedis true (special case).NaN !== NaN, butObject.is(NaN, NaN)is true.Object.is(-0, 0)is false.
1) === vs == in one sentence
===(strict equality): no type conversion==(loose equality): type conversion happens
In production code, prefer === unless you have a clear reason.
2) Truthy / falsy (know this cold)
Falsy values in JS:
false0,-0,0n''(empty string)nullundefinedNaN
Everything else is truthy (including [], {}, '0').
3) Strict equality (===) rules
- different types → false
- primitives compare by value
- objects compare by reference
[] === [] // false
{} === {} // false
const a = {};
const b = a;
a === b // true4) Loose equality (==) rules (the practical set)
Rule A: null and undefined are special
null == undefined // true
null == 0 // false
undefined == 0 // falseInterview-friendly takeaway:
x == nullis sometimes used to mean “null or undefined”
Rule B: If one side is boolean
Convert boolean to number (true → 1, false → 0).
true == 1 // true
false == 0 // trueRule C: If one side is string and other is number
Convert string to number.
'2' == 2 // true
' 2 ' == 2 // true (whitespace trimmed)
'' == 0 // true
'0' == 0 // true
'foo' == 0 // false (Number('foo') = NaN)Rule D: If one side is object and other is primitive
Object is converted to primitive using ToPrimitive.
[1] == 1 // true because [1].toString() -> '1'
[] == 0 // true because [].toString() -> '' then '' -> 0This is why == gets weird.
5) ToPrimitive (why arrays are scary)
When JS converts an object to primitive, it tries:
valueOf()thentoString()(orSymbol.toPrimitiveif present)
Examples:
[] + [] // '' (string)
[] + 1 // '1'
{} + [] // depends on parsing context; often '[object Object]'For interviews, focus on equality examples rather than + operator quirks.
6) The big interview trap list (memorize)
A) [] == ![]
[] == ![] // trueWhy:
![]isfalsebecause[]is truthy- then
[] == false - boolean converts:
false -> 0 []converts to''then number:'' -> 00 == 0→ true
B) '' == 0
'' == 0 // trueC) 0 == '0'
0 == '0' // trueD) 0 == null
0 == null // falseE) NaN comparisons
NaN === NaN // false
NaN == NaN // false
Number.isNaN(NaN) // true7) Object.is vs ===
Object.is is like === except for:
NaN-0
Object.is(NaN, NaN) // true
NaN === NaN // false
Object.is(-0, 0) // false
-0 === 0 // trueInterview take:
- use
Object.iswhen you care about these edge cases.
8) Best practices (what to do in real code)
- Prefer
===and!==. - Use
Number.isNaN(x)for NaN checks. - Use
x == nullonly when you intentionally want null-or-undefined. - Avoid comparing objects directly unless you mean reference equality.
9) Quick practice questions
Predict the output:
console.log([] == 0);console.log('' == false);console.log(null == 0);console.log(Object.is(-0, 0));Summary checklist
- I prefer
===. - I can explain
null == undefinedand whynull == 0is false. - I know
NaN !== NaNandObject.is(NaN, NaN). - I can solve common coercion output questions.
Summary
===is predictable.==follows coercion rules (null/undefined special, boolean → number, string ↔ number conversion, object → primitive).Object.ishandlesNaNand-0differently.- If you can explain 4–5 classic traps clearly, you’re interview-ready.