Unexpected JavaScript...

Every once in a while, I run across something completely unexpected in JavaScript. This morning was one of those times.

In my code, I had the equivalent of this:

var x = 0;
if ('' == x)
    gs.log('What the???');
else
    gs.log('Ah, that was expected!');

Wanna take a guess which statement was logged?

In JavaScript, an empty string evaluates as equal to a zero. Doesn't make any sense to me, but apparently it made sense to a JavaScript designer. I suspect what's going on here is that the empty string is coerced to a number (which would be zero) and is then compared to the number 0 in variable x. What I expected was the opposite: that the number 0 would be coerced to the string '0', and the comparison would have evaluated to a false.

I fixed the code like this:

var x = 0;
if ('' == '' + x)
    gs.log('What the???');
else
    gs.log('Ah, that was expected!');

This forces the coercion to happen as I expected (and wanted) it to.

Another day, another oddity!

Comments


What would be a good use-case for doing this? I'm having trouble following the logic.

If you wanted to ensure that the value within variable x is a string, you could just do a typeof check for 'string'. But that can't be the intention, otherwise you wouldn't be attempting deliberate type coercion. If you wanted to ensure that the variable x held a usable value, you could do another typeof check; this time for 'undefined' first, and then for either 'number' or 'string', and then checked the value or the length accordingly.

Since type coercion in JS can be a bit tricky and work unexpectedly, I typically try to stay away from it when at all possible.


That's the identity operator (the "===") you're talking about, and you're absolutely right that it will not force type coercion. However, it wouldn't help in my circumstance. For example, if I had the following code:

var x = 0;
var y = '0';
gs.log(x === y);

The result would be "false", whereas I'd want that to be true in my original code example. In other words, I actually wanted type coercion, but I wanted it my way!


Not sure if it would fit your uses, but the === comparison operator does not perform type coercion.
Ex:
var x = 10;

x == "10" /* true */
x === "10" /* false */

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.