Writing
JAVASCRIPT

How is == different from === in JavaScript?

When I started with JavaScript, I treated == and === as the same thing with a different number of equals signs. They aren't, and the difference has caught me out more than once.

A code window comparing values with == and ===, with true and false results

The short version

=== checks the type and the value. If the types are different, the answer is false and that's the end of it.

== converts both sides to a common type first, then compares them. That conversion is called type coercion, and it's where the surprises come from.

100 === "100"; // false: a number and a string
100 == "100"; // true: "100" becomes 100

The variables themselves don't change. The conversion only happens for the comparison.

What == converts

The full rules are in the spec, but these cover most of what you'll run into:

  • A number and a string: the string becomes a number.
  • A boolean and anything else: the boolean becomes a number first. true is 1 and false is 0.
  • An object and a primitive: the object becomes a primitive, usually through valueOf() or toString().
  • null and undefined are equal to each other and to nothing else.

The boolean rule is the one that gets people:

true == "true"; // false

true becomes 1. Now it's a number against a string, so "true" becomes a number too, and that's NaN. 1 == NaN is false. You'd never guess that from reading the line.

When I use ==

Almost never. The one case I'm fine with is checking for "no value":

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

It's shorter than checking both, and it's the one place the coercion is easy to predict. Everywhere else I use ===. ESLint's eqeqeq rule will nudge you the same way.

If you're not sure which one you need, use ===. You'll rarely regret it.