Not surprisingly, NaN in Javascript repesents "Not a number." You probably knew that, but here's something you may not have known.
NaN is a 'number'! Well, sort of.
Actually, it's typeof NaN that yields 'number', which, if you ask me, is little bizarre, though not completely illogical (depending on my mood).
It's important to understand the implications here though. Take the following example (something I used to do a lot until recently):
var nBorder = parseInt(strBorder);
if (typeof nBorder == 'number')
{ alert('yep, it\'s a number!'); }
I used to encourage this kind of code (and I still do encourage trying to be "type-safe" (whatever that means to javascript)).
But today I am a little wiser; today I understand that the above code is flawed if my algorithm truely needs a variable of type 'number'.
To understand why, take a look at this modified form of the previous example:
var nBorder = parseInt(strBorder);
if (typeof nBorder == 'number')
{ alert('uh oh!'); }
If you're thinking that that if conditional won't execute, you're wrong. It most certainly will, because as I mentioned at the start of this article, typeof NaN yields 'number'.
Fortunately, the solution is pretty easy. In javascript, there is a simple and convenient isNan(..) function (which, oddly, I knew about, but for some reason never considered using) which will return true if the value you pass in can be interpreted as a number and false if it can't.
Our example would now become:
var nBorder = parseInt(strBorder);
if (!isNaN(nBorder))
{ alert('yep, it\'s a number!'); }
Alternatively, instead of checking for !isNaN(..), you could check for isNaN(..) right at the beginning of your function and simply return prematurely if isNaN(..) is true. A "Design by contract" of sorts (it's a stretch I know, but what do you want from me).
For example:
{
a = parseInt(a);
b = parseInt(b);
if (isNaN(a) || isNaN(b))
{ return; }
alert(a * b);
}
Of course, once you understand isNaN(..), you're free to take whatever action you darn well please. Mine are just silly examples, but I trust you get the point.
It might surprise you to note that isNaN(..) works on strings. So something like isNaN('25') will return true.
Be careful though: isNaN('25px') would return false. You'd have to first run parseInt(..) on your variable, and then it's safe to rely on isNaN(..).
Also, it's worth noting that it's perfectly safe to call parseInt(..) on null or undefined as well as on an empty string ( " ) or ( "" ).
There, a nice short blog entry for those of you who think I write too much
Comments welcome.
2 Responses
Thanks for this!
Thanks a lot for this article. You helped me solve a 'mystery' in my logic that was bugging me for sometime!