Bitsy Explains
Home/JavaScript, Explained Like You're Five/Lesson 2

== vs === in JavaScript

== converts values to the same type before comparing, so different things can look equal. === checks the value and the type, which makes it the safe default.

Lesson 2 of 203 min readVideo
Video thumbnail: == vs === Watch the 90-second video
Explain like I'm five

Put the number 5 next to a sticky note with "5" written on it. Double equals squints at them and says close enough, same thing. Triple equals grabs a magnifying glass, sees that one is a number and one is text, and says they are not the same.

Two ways to ask "are these equal?"

Both == and === compare two values and give you true or false. When the two values are the same type, like two numbers or two strings, they behave the same way. The difference shows up when the types don't match, and that's where == starts guessing.

Early JavaScript tried to be helpful and guess what you meant. == is that guess. Guessing causes surprises, so === checks exactly.

What == does: type coercion

console.log(5 == "5"); // prints: true
console.log(5 === "5"); // prints: false
console.log(typeof 5, typeof "5"); // prints: number string

A string just means text. Before comparing, == quietly turns the string "5" into the number 5. Changing one type into another like this is called type coercion.

=== skips that step. It checks the value and the type, and a number is never the same type as a string, so the answer is false.

The hall of weird

Type coercion follows fixed rules, but they lead to some strange results.

console.log(0 == ""); // prints: true
console.log("1" == true); // prints: true
console.log([] == false); // prints: true
console.log(0 === "", "1" === true, [] === false); // prints: false false false

Here is what == does step by step:

  • 0 == "": the empty string becomes the number 0, and 0 equals 0.
  • "1" == true: true becomes 1, then "1" becomes 1.
  • [] == false: false becomes 0, the empty array becomes the empty string "", and that becomes 0.

Each step makes sense on its own, but nobody wants to work them out while reading code. === says no to all of it.

The twist: NaN

NaN means Not a Number. You get it from math that has no sensible answer, like turning the word "cookie" into a number. It is the only value in JavaScript that isn't equal to itself, even with ===.

const result = Number("cookie");
console.log(result); // prints: NaN
console.log(result === NaN); // prints: false
console.log(Number.isNaN(result)); // prints: true

So never test for NaN with ===. Use Number.isNaN() instead.

You may also find an older function called plain isNaN(). It converts its input to a number first, so isNaN("cookie") is true even though "cookie" is a string. That's the same kind of guessing == does. Number.isNaN() only says true for the real NaN value.

The one place you may see ==

Some code uses value == null on purpose. It is true for both null and undefined and nothing else. Some teams allow that single use. If you're not sure, write === and compare exactly what you mean.

Rule of thumb

Use === by default, and skip == until you really know how it converts things.

Common mistake

Comparing text typed into a form with a number, like age === 7. Form input is always a string, so this is false even when someone typed 7. Convert it first with Number(age) === 7.

Check yourself

Why is 5 == "5" true?