== vs ===: Understanding JavaScript Equality

Learn the difference between loose and strict equality in JavaScript.

The Simple Rule

Always use === (strict equality) unless you have a specific reason to use ==.

== (Loose Equality)

The loose equality operator performs type coercion before comparing:

1 == '1'      // true (string converted to number)
0 == false    // true (false converted to 0)
null == undefined  // true (special case)
'' == 0       // true (empty string converted to 0)

=== (Strict Equality)

The strict equality operator compares both value and type:

1 === '1'     // false (different types)
0 === false   // false (different types)
null === undefined  // false (different types)
'' === 0      // false (different types)

Why === is Better

1. Predictable Behavior

// With ==, these are all true (confusing!)
0 == ''      // true
0 == '0'     // true
'' == '0'    // false (wait, what?)

// With ===, it's clear
0 === ''     // false
0 === '0'    // false
'' === '0'   // false

2. Avoids Bugs

function isValid(value) {
  // Bug: 0 and '' would pass with ==
  if (value == null) return false;
  return true;
}

isValid(0);    // true (maybe not intended)
isValid('');   // true (maybe not intended)

// Better:
function isValidStrict(value) {
  if (value === null || value === undefined) return false;
  return true;
}

When to Use ==

There's one legitimate use case for ==:

// Checking for null OR undefined
if (value == null) {
  // value is null or undefined
}

// Same as:
if (value === null || value === undefined) {
  // ...
}

But with modern JavaScript, you can use nullish coalescing instead:

const result = value ?? 'default';

Type Coercion Table

x y x == y x === y
1 '1' true false
null undefined true false
0 false true false
[] false true false
'' false true false

Best Practice

Configure your linter to enforce === (eqeqeq rule in ESLint).

{
  "rules": {
    "eqeqeq": "error"
  }
}

Summary

  • === compares value AND type (strict)
  • == compares value after type coercion (loose)
  • Always use === unless you specifically need type coercion
  • Most == usage is unintentional and causes bugs