Double Equals Comparison Operator in JavaScript

I’ve been doing a lot of development in JavaScript lately. I’ve found that evaluating values using the double equals comparison operator in JavaScript can produce some intriguing results.

First, I want to clarify the difference between double equals (==) and triple equals (===) in JavaScript. Double equals evaluates equality WITH type coercion while triple equals evaluates equality WITHOUT type coercion. Thus:

0 == false     //true
0 === false    //false

Double Equals (==)

Now for some more examples. For starters, when comparing '0' and '' to false, both evaluate to true:

'0' == false    //true
'' == false     //true

However, when we compare them against each other:

'0' == ''   //false

Interesting. Why is that? This is how the double equals works:

Equal (==)

If the two operands are not of the same type, JavaScript converts the operands then applies strict comparison. If either operand is a number or a boolean, the operands are converted to numbers if possible; else if either operand is a string, the other operand is converted to a string if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory (Comparison Operators, Mozilla Developer Network).

So, with the example at hand, JS evaluates the operand type first. Since neither operand is a number or boolean and at least one of the operands is a string, they are evaluated as strings. (In this case, just so happens both operands are strings.) Next JS evaluates the values, which are different. Despite the “falsey” nature of both zero and the empty string, as string types they are altogether different values and therefore not equal.

Let’s take a look at a couple other intriguing examples.

'' == '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

To explain some of these examples that were perplexing to me the first time I examined them…

When comparing false == 'false', JS tries to convert both to numbers. The result is 0 === NaN, which is of course false. This also explains why false == '0' is true–because it boils down to 0 === 0.

It appears that when ' \t\r\n ' is converted to a number, JS converts it to 0. At any rate isNaN(' \t\r\n ') results in false, which tells me that when converted to a number, ' \t\r\n ' does NOT result in NaN. Therefore ' \t\r\n ' must boil down to 0 since ' \t\r\n ' == 0 is true.

For further reading and in depth analysis with helpful tables, I highly suggest reading Truth, Equality and JavaScript by Angus Croll.

Final Thoughts

Some developers avoid using == in their code because they don’t understand it and it’s confusing. I think it’s important to understand how == works since this will lead to language mastery. Furthermore, if you don’t use ==, your colleagues or 3rd party libraries will, and if you don’t understand it, then you are disempowered. After you understand ==, I see no problem with not using it. But simply avoiding it because it’s confusing and you don’t understand it seems unwise.

If performance is of concern when using == vs ===, these may be worth perusing:

More JavaScript