How to avoid automatic type conversion in JavaScript
A very common problem when people code JavaScript, is that they don’t take automatic type conversion into account. As a result, there are numerous weird errors and JavaScript is getting a lot of blame for being loosely typed. Therefore, I’d like to show you an easy way to avoid that problem.
Most people write comparison checks just like they would in any other language. E.g:
if (valueOne == valueTwo)
The thing with JavaScript, though, is that if the values are of different types but seem to consist of the same value, a conversion is taking place, changing the type of one or several of the values. For instance, this equals true
:
5 == "5"
The reason is that the values are converted into the same type, and then compared, hence the result becomes true. Also, this goes for all different types in JavaScript. A good way to make this never happen is to use type and value checking, like this:
5 === "5"
or this:
5 !== "5"
By using three equal signs or one exclamation sign and two equal signs, it also makes sure to compare if the values are of the same type or not, i.e. both being numbers, strings etc. This is also a practice recommended when working with JSLInt.
So, from now, don’t forget the type checking availability in JavaScript!
Loose typing is one of my favourite things in JavaScript (and any other language I can find it in). Maybe because I expect things to be loose (yeah, you should see me try to program in Java) I don't tend to have problems with them.
Good tip though! If this does present a problem, I'll know what to do.
It is indeed a very common problem, which most of the developers I have encountered are sadly not aware of…
I tend to "validate" my javascript code with JSLint on a regular basis, and it has already helped me prevent and/or correct a few bugs. Once you know how to configure it, it is really helpful.
Thanks for the reminder Robert, I haven't checked my code with JSLint in a while π
My favorite one is this one:
<code>
alert({toString:function(){return "null"}} == "null");
</code>
π
Can you guess what this equates to:
<code>alert('2' * '2' + 1 + '3' + 7);</code>
The * converts strings to ints, then the + is used as addition. The '3' means the 2nd + is concatenate, turning it into a string, so the final + 7 is also concatenate. As always, be careful getting ints from the user, and be careful with +. Similar problems in PHP too.
PS, Comment preview is very cool.
Glad to help!
Andrea, Dave,
Those are just wonderful! π
Thanks for pointing them out.
Dave,
Thanks!
Since I use JSLint I have no choice but using ===. Which is a good thing. In fact I only used == before reading a similiar post somewhere, and that's now allready a moment far away in the cold mists of time….
Admitted, before that day sometimes I pulled my hairs wondering "wtf". Eternal thx to whoever pointed it out then, and good work Robert on spreading the word.
In short: === rocks. Back to the beer π
One of the causes, as in Andrea's example, is that the same operator is used for addition and concatenation. I find Perl's .-operator much smarter is this kind of circumstances. Of course, in some ways, concatenation can be seen as addition for strings so it makes sense in a semantic way, I guess.
Stefan,
Yes, it's a great thing to avoid all those weird errors.
Berserk,
Granted, type checking by default would have been nice, although it's looseness has also made it extremely flexible. I guess it's all about doing the best you can with the tools at hand.
Robert,
Ran into this when I googled for "Automatic Type Conversion in JavaScript".
Thanks for this advice. But I am not sure if this is enough for us to "avoid" the automatic type conversion in JavaScript code (maybe it is, as far as equality operators are concerned). As I read David Flanagan's excellent reference on JavaScript, I stumbled upon the type-conversion summary and operator summary tables he's provided. Studying them, I come to a conclusion that it's the operators that decide how the automatic conversion occurs (thereby deciding the context of an expression). Whereas it's a great advice to use === and !== in lieu of == and !=, automatic type conversion will still happen when an operator expects operand(s) of a particular type and receives operands of some other type. e.g.:
<code>
var empty="";
var c = !empty;
</code>
will make c a boolean with a value true assigned to it. Here, as long as I understand, the automatic type conversion happens because the Logical Not (!) operator expects its operand to be boolean, but receives a string and hence the string gets converted to a boolean (false) and the entire expression evaluates to true.
Am I understanding it correctly?
Regards,
Kedar
(A JavaScript novice)
Kedar,
Absolutely, this is just one way to protect us, but there are other scenarios where we could get into trouble. Your example there is a bit tricky, because an empty string is converted to the boolean value false in such a check (so would also the value
null
, the number 0 and an undefined variable become).I have a a few examples of how it works and what to do and expect in my JavaScript presentation: JavaScript – From Birth to Closure.
In general, though, the advice is to use
typeof
,parseInt
and similar approaches to make your code more safe.