Tales from the Evil Empire

Bertrand Le Roy's blog

News

Ads Via DevMavens

ASP.NET AJAX UpdatePanel Control: Add Ajax interactivity to your ASP.NET 2.0 web pages

Add to Technorati Favorites

Blogs I read

My other stuff

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.

Comments

Wim Hollebrandse said:

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

Loose typing.
# January 26, 2006 7:26 AM

Aapo Laakkonen said:

Another workaround:

Use strict equality operators: === and !==.
# January 26, 2006 7:30 AM

Aapo Laakkonen said:

Yet another workaround for older browsers (IE4 and below and old netscape browsers):

((typeof("") == typeof(0)) && ("" == 0))

And why it's like that:

http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Operators:Comparison_Operators
# January 26, 2006 7:43 AM

Ron Buckton said:

== 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
# January 26, 2006 9:44 AM

Alan Oursland said:

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.
# January 26, 2006 12:02 PM

Bertrand Le Roy said:

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.
# January 26, 2006 12:18 PM

Christian Wenz said:

if you do PHP a lot, you get used to these built-in type conversions ... :-)
# January 30, 2006 11:56 AM

Eric Lippert said:

> 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.
# January 30, 2006 1:20 PM

Bertrand Le Roy said:

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.
# January 30, 2006 2:10 PM

Atlas and more said:

Here are three common mistakes I've seen recently in script files.Undefined is not null.If you've

# October 12, 2006 2:32 PM

Dougal said:

Dude you just don't know how to code in a dynamic language if you think == is an error. pfft.

# November 28, 2007 12:15 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)