Neil's News

== vs ===

7 June 2017

JavaScript has two equality operators, == and === (not to mention their negative equivalents, != and !==). The difference is that == checks if the two operands are equivalent to each other, whereas === checks that the two operands are equivalent and of the same type. For example:

This distinction becomes even more important in the realm of false values. In each of the cases below == evaluates to true, whereas === evaluates to false:

Clearly there are a few times when == is the operator one wants to use, and there are also significantly more times when === is the operator one wants to use. But the overwhelming majority of equality checks don't fall into either category. Most equality checks are something like if (i == str.length) where both i and length are known to be integers. So which operator should one use by default?

Reasons to prefer ===

Douglas Crockford famously describes == and != as being "evil" and "alarming". He advises that they should never be used since they can produce unexpected results. It is unreasonable to assume that even the most experienced JavaScript programmer would intuitively expect that [[]] == '' is true.

The equality operator of most other programming languages is type-aware; JavaScript's === is the equivalent of == in Java, Python, etc. Thus if one is primarily based in another language, then using === is smart since the behaviour is equivalent and there will be fewer surprises.

Since the == is casting the value before checking, it's logical to assume that it is slower to evaluate than the stricter ===. This is a commonly raised argument, though it is contradicted by all available data which shows no performance difference between the two.

Reasons to prefer ==

Google's JavaScript style guide is silent on the matter, but Closure (Google's core JS library) is consistent in preferring == to === (7 to 1). The main reason is that unintentional comparisons of values of different types are simply bugs. The solution is to fix the bugs, not to evaluate to false. If one is evaluating [[]] == '' then the likelihood is that there's something wrong upstream. A stricter equality merely masks the issue and is thus detrimental.

By consistently preferring ==, that means that encountering a === sets off alarm bells. There are some strange values at play (often null or undefined) that are being considered. For example if (x === 0) implies that x might not always be an integer and one has to be careful.

Boxed values are a pain in the neck with strict equality. 'hello' === new String('hello') evaluates to false, which is never the expected behaviour. Using == makes the entire problem of boxed values go away. Boxed values should be avoided in any case, but they do inadvertently pop up now and then (such as 'this' in call/apply).

A fringe benefit is that '==' is one byte shorter than '==='. At scale this adds up to terabytes of saved bandwidth and hours of reduced waiting.

There is no right or wrong choice on this matter. Being consistent with the code around you is probably the most important factor to consider. For me personally, after more than ten years of using == at Google, I've never stumbled into one of the negative Wat cases. Quite the contrary, I'm routinely helped by the comparative rarity of === and its implied warning that something strange is happening with types.

< Previous | Next >

Legal yada yada: My views do not necessarily represent those of my employer or my goldfish.