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.

F

Frontend Interview Team

February 08, 2026

~22 min
JavaScript Equality & Type Coercion: == vs === (With Interview Traps)

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 == undefined is true (special case).
  • NaN !== NaN, but Object.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:

  • false
  • 0, -0, 0n
  • '' (empty string)
  • null
  • undefined
  • NaN

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 // true

4) Loose equality (==) rules (the practical set)

Rule A: null and undefined are special

null == undefined // true
null == 0         // false
undefined == 0    // false

Interview-friendly takeaway:

  • x == null is 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 // true

Rule 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 '' -> 0

This is why == gets weird.


5) ToPrimitive (why arrays are scary)

When JS converts an object to primitive, it tries:

  • valueOf() then toString() (or Symbol.toPrimitive if 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) [] == ![]

[] == ![] // true

Why:

  • ![] is false because [] is truthy
  • then [] == false
  • boolean converts: false -> 0
  • [] converts to '' then number: '' -> 0
  • 0 == 0 → true

B) '' == 0

'' == 0 // true

C) 0 == '0'

0 == '0' // true

D) 0 == null

0 == null // false

E) NaN comparisons

NaN === NaN // false
NaN == NaN  // false
Number.isNaN(NaN) // true

7) 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            // true

Interview take:

  • use Object.is when you care about these edge cases.

8) Best practices (what to do in real code)

  1. Prefer === and !==.
  2. Use Number.isNaN(x) for NaN checks.
  3. Use x == null only when you intentionally want null-or-undefined.
  4. 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 == undefined and why null == 0 is false.
  • I know NaN !== NaN and Object.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.is handles NaN and -0 differently.
  • If you can explain 4–5 classic traps clearly, you’re interview-ready.