How Double-Equals Works in JavaScript
tl;dr — Don’t use double-equals!
When asked about the difference between double and triple-equals, a lot of JS developers will tell you that ==
compares values and ===
compares values and types. In other words, 1 == "1"
will be true, and 1 === "1"
will be false.
That explanation is somewhat true, but it belies a much more complicated reality.
Some of the confusion comes from thinking that ==
is somehow related to truthiness, which is all about how variables get coerced into booleans — which happens in an if statement like this:
if (something) {
In that case — 0
, ""
the empty string, null
, undefined
, and NaN
will all return false. Non-zero numbers, Non-empty strings, arrays and objects (empty or not) will all return true. Most devs have a pretty good handle on this.
But… does that mean that a non-zero number, or all non-empty strings will double-equal true? This is where things can get confusing.
if ('a') { // true if ('a' == true) { // false if ('a' == false) { // false if (2) { // true if (2 == true) { // false if (1 == true) { // true
Hopefully that makes it clear that truthiness has nothing to do with ==
.
Remember: truthiness is about coercion into booleans. With double-equals, nothing will ever get coerced into a boolean. So what’s really going on?
The answer is the Abstract Equality Comparison Algorithm. If the two types differ, JS follows a particular process for converting them into the same type, so that it can compare them. If types don’t match somewhere along the way — the endgame will be numbers.
- First, booleans are converted to numbers.
True
becomes1
andfalse
becomes0
. - Next, objects will be turned into strings using
.toString()
(unless you modified.valueOf()
to return a primitive). So[1]
becomes"1"
,[1,2]
becomes"1,2"
, and both{...}
and[{...}]
become"[object Object]"
. - If a string and a number are left, the string is converted to a number (so any string with non-number characters will become
NaN
— which, by the way, never ever equals anything, including itself). null
andundefined
equal themselves and each other.
That’s the gist of it, but you can check out the spec for more details.
So — do you need to remember all these rules? Absolutely not. As Felix Geisendörfer puts it, “Programming is not about remembering stupid rules. Use the triple equality operator as it will work just as expected.”
That’s why most all JS style guides recommend using only ===
. Some allow for an exception when checking for null or undefined (by using “== null
“). But some folks would argue against even that.