tags:

views:

309

answers:

6

I was debugging something and discovered some strangeness in JavaScript:

alert(1=='') ==> false
alert(0=='') ==> true
alert(-1=='') ==> false

It would make sense that an implied string comparison that 0 should = '0'. This is true for all non-zero values, but why not for zero?

+2  A: 

Javascript, like PHP, is weakly typed*. So when you compare 0 to '', the JS engine converts them to a similar datatype. Since 0 and '' both equate to boolean(false), "false == false" is true.

*Weakly typed languages do not require variables to be any specific data type, so you can set one variable as a string, change it to int, float, and back to string without the processor throwing errors.

davethegr8
+1 Very nice - do you know how the engine decides which datatype to convert to? Obviously converting 0 to a string would not have the same results.
Andrew Hare
This is wrong - '' will be converted to 0, not boolean `false`
Christoph
No, I'm not sure. I would suspect that it's a numerical type, or a boolean cast.
davethegr8
I don't think this explanation is accurate. Both 0 and '' are not converted to false before the comparison. See RoBorg's answer [http://stackoverflow.com/questions/462663/implied-string-comparison-0-but-11#462713]
Grant Wagner
check my answer - I looked it up, and the standard says the string will be converted to number!
Christoph
@Christoph - I didn't mean that they are converted to booleans, I meant that they are converted to similar types. And they also equate to false.
davethegr8
@davethegr8: it might be true that they both evaluate to false in boolean contexts, but what relevance does this have to the question?
Christoph
That on some level, they are equivalent. I wasn't certain of the details, but there's a much better explanation: http://stackoverflow.com/questions/462663/implied-string-comparison-0-but-11#462713
davethegr8
+3  A: 

This is just one of the truly hideous mangles that went into the JavaScript compromise. '' and 0 are both uninitialized values (equal to boolean false) and, therefore, equal.

To protect yourself from weird bugs like this, it's better to always use the === operator.

Jekke
0 and '' are not uninitialized values. They are values that are implicitly type converted to the same value when compared.
Grant Wagner
+4  A: 

When javascript does implicit type conversions, the empty string literal will match the 0 integer. Do your comparison like this and you'll get your expected result:

alert(1==='') ==> false
alert(0==='') ==> false
alert(-1==='') ==> false
Joel Coehoorn
+2  A: 

In many languages, the empty string can be coerced to false.

Beware of doing comparisons with == instead of ===:

alert('' == '0'); //false  
alert(0 == ''); // true  
alert(0 =='0'); // true

== is not transitive.

Michael Deardeuff
+3  A: 

ECMA-262, 3rd edition, 11.9.3 regarding x == y, step 16:

If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y).

The empty string '' gets converted to 0 before the comparison.

Christoph
+1 but making the spec cite a link would be nice
Greg
@RoBorg: linking doesn't work with PDFs, and googling ECMA-262 and clicking the first link isn't that much of an inconvenience..
Christoph
@Christoph neither is googling for "javascript equality operator" but that's not the point
Greg
@RoBorg: my point was that it's *impossible* to deep link to the correct section, and providing a link to a readily available standards document isn't really one of my priorities - so what *is* your point?
Christoph
+5  A: 

According to the Mozilla documentation on Javascript Comparison Operators

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 either operand is a string, the other one is converted to a string

What's actually happening is that the strings are being converted to numbers. For example:

1 == '1' becomes 1 == Number('1') becomes 1 == 1: true

Then try this one: 1 == '1.' becomes 1 == Number('1.') becomes 1 == 1: true If they were becoming strings, then you'd get '1' == '1.', which would be false.

It just so happens that Number('') == 0, therefore 0 == '' is true

Greg