I love Javascript!

Just kidding. But I think that got your attention :)
Seriously, there are things I really like about Javascript (like it being a dynamic language), but some things are just... So unexpected they just look plain wrong.
For instance, what do you think this evaluates to:

"" == 0

Of course, I gave you enough clues for you to guess that it does return the wrong thing. Yes, this is actually true. Empty string equals zero. Isn't that a beautiful feature? Isn't that going to make your life so much easier? No? Really? Well, I agree with you, this is FUBAR.
While I can understand that Javascript would evaluate both empty string and zero to be equivalent to false in contexts where a bool is expected, I would expect both sides of an == operator not to be such a place. To tell you the truth, I think it's kind of wrong even in boolean contexts because it's a bug attractor, but anyways.
If anyone has a reasonable explanation for this, I'm all ears.
Oh, and about a workaround... You can use toString() on both sides of the equals operator once you've checked that they are not undefined or null.

UPDATE: as some have pointed out in comments (and I should have researched that), you can use the strict equality operators (=== and !==) and get the expected results on recent browsers (on older browsers you can compare the types as well).
In a nutshell, I think the problem here is that the initial specification for the == operator was absolutely wrong, but changing it would have been a breaking change so they had to add the === operator to finally get it right. So for all useful purposes, I can see no reason to use == instead of === except to save one character.

8 Comments

  • I guess the explanation for this is down to one thing:



    Loose typing.

  • Another workaround:



    Use strict equality operators: === and !==.

  • == In javascript is a lazy comparison operator and makes an effort to normalize the values before the comparison. If you want a strong comparison operator that also compares types, use ===. This is the strict equality operator.



    ""==0 // true

    ""===0 // false

  • Here is a theory:

    An empty string is a length 1 array containing '\0' (which is equal to zero). Javascript automatically casts single length strings to characters and vice versa. '\0' == 0 therefore "" == 0.

  • Loose typing is not enough to explain it: Javascript could very well just do the implicit cast to bool only in a boolean context. Instead, it's booleans that are converted to numbers.

    Thanks for all the workarounds, which are of course better than the toString thing.

    Updating the post.

  • if you do PHP a lot, you get used to these built-in type conversions ... :-)

  • > If anyone has a reasonable explanation for this, I'm all ears.



    This is a consequence of two simple rules.



    1) When comparing a string to a number, convert the string to a number.



    This makes more sense than converting the number to a string. After all, you would like "1.010" to compare equal to 1.01, right?



    2) Empty or all-whitespace strings convert to zero.



    This is maybe a little more borderline weird, but it makes some sense.



    Once you have these two rules in place, 0 == "" --> true is an obvious consequence.



    >Oh, and about a workaround... You can use toString() on both sides of the equals operator once you've checked that they are not undefined or null.



    A better workaround is:



    a + "" == b + ""

    a - 0 == b - 0

    !a == !b

    a === b



    which force string, numeric, boolean or strict comparisons respectively.



    > changing it would have been a breaking change so they had to add the === operator to finally get it right



    No, the === operator was added because strict type comparison semantics are necessary to implement a sensible switch statement, which was not in the original Netscape version of ECMAScript. It would be really weird if you could create a switch statement but not the equivalent series of if statements, so we added a strict type equality operator.

  • Eric: Thanks for the comment, I really appreciate, and as I've said, there are things I really do love about Javascript. I understand all that (and have actually included one of the better workarounds), but I don't think it qualifies as a reasonable explanation, it just reinforces the idea that the need for strict comparison was an afterthought and that's how the == operator should have worked from the start (that's how it works in some other dynamic languages).

    I just don't see any good reason to use == in place of === except to save one char as === always just does the expected thing.

Comments have been disabled for this content.