Home/Learn/JavaScript & TypeScript/Equality & Coercion — == vs === and Why It Matters

Equality & Coercion — == vs === and Why It Matters

Beginner
Language Core

JavaScript will convert types to make a comparison succeed. == does this conversion, === does not, and knowing the handful of rules turns "weird" behaviour into predictable behaviour.

Overview

Coercion is the feature people cite when they call JavaScript a bad language, and it is genuinely the source of real bugs. But the rules are short. The loose equality operator == converts operands to a common type before comparing; strict equality === compares type and value with no conversion. The practical advice is simple — use === always, with exactly one useful exception — but you still need to read the rules, because you will encounter == in other people's code and in every interview.

The Rules Worth Memorising

Loose equality has a specific algorithm. These are the cases that actually appear in real code and interviews.

Loose equality, in the cases that matter
// Strict: no conversion, compares type then value
1 === '1'          // false
null === undefined // false

// Loose: converts first
1 == '1'           // true  — string becomes number
0 == false         // true  — boolean becomes number
'' == false        // true  — both become 0
null == undefined  // true  — special-cased in the spec
null == 0          // false — null only equals undefined

// The one genuinely useful ==
if (value == null) {
  // true for BOTH null and undefined, nothing else
}
// same as: value === null || value === undefined

Truthiness

Every value is either truthy or falsy in a boolean context. There are exactly eight falsy values; memorise those and everything else is truthy — including empty arrays and empty objects, which surprises people coming from Python.

Eight falsy values, and the bug they cause
// The complete falsy list:
false, 0, -0, 0n, '', null, undefined, NaN

// Everything else is truthy, including:
if ([])  {}        // runs — empty array is truthy
if ({})  {}        // runs — empty object is truthy
if ('0') {}        // runs — non-empty string

// The classic bug:
function setCount(n) {
  if (!n) return          // 0 is falsy — this rejects a valid 0
  ...
}
// Fix: be explicit about what you are rejecting
if (n === undefined) return

?? and ?. — The Modern Fixes

Nullish coalescing and optional chaining exist specifically to avoid the truthiness trap. ?? falls back only on null or undefined, where || falls back on any falsy value.

The operators that replaced defensive checks
// || falls back on ANY falsy value — usually not what you want
const pageSize = input.size || 20     // 0 becomes 20. Bug.

// ?? falls back only on null/undefined
const pageSize = input.size ?? 20     // 0 stays 0. Correct.

// Optional chaining short-circuits instead of throwing
const city = user?.address?.city      // undefined if either is missing
const first = list?.[0]
const result = callback?.()           // only calls if callback exists

// Combined, the common shape when reading API responses:
const name = response?.data?.user?.name ?? 'Anonymous'

Key Points to Remember

  • 1=== compares type and value with no conversion; == converts first — default to === always
  • 2value == null is the one useful loose comparison: true for null and undefined, nothing else
  • 3Exactly eight falsy values: false, 0, -0, 0n, "", null, undefined, NaN — empty arrays and objects are truthy
  • 4?? falls back only on null/undefined, || falls back on any falsy value — using || for defaults breaks on 0 and ""
  • 5?. short-circuits to undefined instead of throwing, which is what makes reading nested API responses safe

Interview Questions

Sign in to ask Aria
1

What is the difference between == and ===? When would you deliberately use ==?

Easy
2

List the falsy values in JavaScript. Is an empty array truthy or falsy?

Easy
3

Why does `const size = input.size || 20` have a bug, and how does ?? fix it?

Medium

Ask Aria about Equality & Coercion — == vs === and Why It Matters

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…