In JavaScript, the Good Parts, Douglas Crockford wrote:
JavaScript has two sets of equality operators:
===
and!==
, and their evil twins==
and!=
. The good ones work the way you would expect. If the two operands are of the same type and have the same value, then===
producestrue
and!==
producesfalse
. The evil twins do the right thing when the operands are of the same type, but if they are of different types, they attempt to coerce the values. The rules by which they do that are complicated and unmemorable. These are some of the interesting cases:'' == '0' // false 0 == '' // true 0 == '0' // true false == 'false' // false false == '0' // true false == undefined // false false == null // false null == undefined // true ' \t\r\n ' == 0 // true
The lack of transitivity is alarming. My advice is to never use the evil twins. Instead, always use
===
and!==
. All of the comparisons just shown producefalse
with the===
operator.
Given this unequivocal observation, is there ever a time when using ==
might actually be appropriate?
Best Answer
I'm going to make an argument for
==
Douglas Crockford which you cited is known for his many and often very useful opinions. While I'm with Crockford in this particular case it's worth mentioning it is not the only opinion. There are others like language creator Brendan Eich who don't see the big problem with
==
. The argument goes a little like the following:JavaScript is a behaviorally* typed language. Things are treated based on what they can do and not their actual type. This is why you can call an array's
.map
method on a NodeList or on a jQuery selection set. It's also why you can do3 - "5"
and get something meaningful back - because "5" can act like a number.When you perform a
==
equality you are comparing the contents of a variable rather than its type. Here are some cases where this is useful:.value
of an input element in the DOM? No problem! You don't have to start casting it or worrying about its type - you can==
it right away to numbers and get something meaningful back.== null
it since behaviorallynull
represents there is nothing there andundefined
doesn't have anything there either.false
with the==
argument, it will treat cases the user has entered nothing or just white-space for you which is probably what you need.Let's look at Crockford's examples and explain them behaviorally:
Basically,
==
is designed to work based on how primitives behave in JavaScript, not based on what they are. While I don't personally agree with this point of view there is definitely merit in doing it - especially if you take this paradigm of treating types based on behavior language-wide.* some might prefer the name structural typing which is more common but there is a difference - not really interested in discussing the difference here.