Blog/Jul 24, 2026/JavaScript/junior/2 min read

== vs === in JavaScript: The Complete Guide

The difference between == and === explained — what coercion does, why === is safer, and the edge cases that show up in JavaScript interviews.

javascriptequalitycoercion

=== is the safest default in JavaScript: it compares both value and type, with no coercion. == converts operands to a common type first, which is where the surprising results come from. That's the whole difference — the rest is edge cases.

What coercion does

With ==, when the two operands have different types, JavaScript tries to make them the same type before comparing:

"5" == 5;     // true  — string coerced to number
0 == false;   // true  — false coerced to 0
null == undefined; // true — the one pair that's special

With ===, no conversion ever happens. Different types is an instant false:

"5" === 5;    // false
0 === false;  // false
null === undefined; // false

The coercion rules worth knowing

The full == algorithm is long, but the parts that show up in interviews:

  1. If both are the same type, == behaves like ===.
  2. If one is a number and the other a string, the string becomes a number.
  3. If one is a boolean, the boolean becomes a number first (true → 1, false → 0) — then the above applies.
  4. If one is an object and the other is a primitive, the object calls valueOf()/toString().
  5. null == undefined is true; null === undefined is false. This one special case is why many codebases write == null to check "null or undefined."

The boolean step is the source of most surprises:

[] == false;  // true — [] → "" → 0, and false → 0
[0] == false; // true — [0] → "0" → 0
[] == ![];    // true — famous trap

Why === is the safer default

Predictability. =='s coercions are almost never what you meant. " " == 0 is true; "abc" == NaN is false even though "abc" is NaN as a number — coercion makes reasoning hard.

Rules most teams adopt:

  • Default to === everywhere.
  • The one acceptable == is == null (checks both null and undefined). Some prefer explicit === null || x === undefined instead.
  • For comparing objects, neither works — === on two objects compares references, not contents. That's what a deep-equality utility is for.

The interview answer

If an interviewer asks, the score-raising shape is: "=== compares value and type without coercion; == coerces first. I default to === for predictability, and I know the coercion table — including null == undefined — so I'm never surprised when == appears in legacy code."

Then, if they push on NaN: NaN is not equal to anything, including itself — NaN === NaN is false — which is why Number.isNaN() exists.

Related guides