Why does 1==1==1 return true, "1"=="1"=="1" return true, and "a"=="a"=="a" return false? [duplicate]

function a() { return (1 == 1 == 1); }
function b() { return ("1" == "1" == "1"); }
function c() { return ("a" == "a" == "a"); }

I tested the above code in Chrome's console and for some reason, a() returns true, b() returns true, and c() returns false.

Why is this so?


Solution 1:

Because you are comparing the (boolean) result of the first equality with the (non-boolean) third value.

In code, 1 == 1 == 1 is equivalent to (1 == 1) == 1 is equivalent to true == 1.

This means the three methods can be written more simply as:

function a() { return (true == 1); }
function b() { return (true == "1"); }
function c() { return (true == "a"); }

These comparisons work according to these rules (emphasis mine):

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 string operand is converted to a number if possible. If both operands are objects, then JavaScript compares internal references which are equal when operands refer to the same object in memory.

So what happens in c is that "a" is converted to a number (giving NaN) and the result is strictly compared to true converted to a number (giving 1).

Since 1 === NaN is false, the third function returns false. It's very easy to see why the first two functions will return true.

Solution 2:

Because 1 == true

But "a" != true

So basically what happens is that

1 == 1, "1" == "1" and "a" == "a" are all evaluated to be true and then compared to the next value.

The string "1" is converted to a number (1) prior to being compared to true and is thus also considered to be equal to true.

Now, the "WHY?!?!" question is explained by the fact that Javascript has its roots in the C-family of languages. In which any number, other than 0 is considered to be a valid true boolean. :-/