 # Michele Nasti

Thoughts on what I learn # Not-A-Number: when javascript gets crazy

Yesterday I was doing some maintenance on a corporate website when I found out that `parseInt()` returns `NaN` if the argument is, well, not a number. ``> let pippo = parseInt('a')NaN``

`NaN` is a constant and stands for `Not a Number`. Javascript uses this for some very default cases, for example if you divide a number by a string, etc.

That's fair. What comes next is funny :)

``> pippo == NaNfalse> pippo === NaNfalse``

Even if a variable is `NaN`, you cannot check with the usual operators that it is `NaN`.

``> pippo == pippofalse> pippo === pippofalse> NaN == NaNfalse> NaN === NaNfalse``

Things start to get crazy. As you can see, `NaN` is not even equal to itself. You cannot compare anything to `NaN`, because `NaN` is not equal to anything.

## sooooo... isNaN() ?

There is a function called `isNaN()` and it's the only way to detect a `NaN`.

``> isNaN(pippo)true> isNaN(3)false> isNaN('bau bau micio micio')true``

This function seems to resolve our problems: it detects not-numbers, and infact a string is considered `NaN`.

``> isNaN(undefined)true> isNaN(null)false``

I see your face 😆 Where is the logic?

`isNaN` tries to convert the argument to a number, using the constructor `Number()`; if the argument cannot be converted, `NaN` is returned.

In the case of `isNaN(null)`, this is what happens:

``isNaN(null) // Number(null) ==> 0 > false ``

Ha ha, `Number(null)` returns zero??? Welcome to javascript 😎 This would require a bigger explanation, however JS does a type cohercion trying to compare things. It is described here (warning: it's a spec, the first 10 lines are understandable, then it's a mess).

Of course,

``null == 0> false``

🙂

Just to add the last bit of discoveries around `NaN`:

``Number(null)> 0parseInt(null) > NaN``

## There is another isNaN() around

The Javascript `Number` object also has a `isNaN` method, that is way more conservative:

``> Number.isNaN(3)false> Number.isNaN('3a')false> Number.isNaN('abc')false> Number.isNaN(undefined)false> Number.isNaN(null)false> Number.isNaN(NaN)true``

It will return `true` only for `NaN`.

## Stop this! It's a mess!

Ok, let's end with a song:

``console.log(`\${10/'a'}a\${ 10/'b'}a\${ 10/'c'}a\${10/'d'}a \${10/'e'}a\${10/'f'}a\${10/'g'}a\${ 10/'h'}a Batman!`)//NaNaNaNaNaNaNaNa NaNaNaNaNaNaNaNa Batman!``