# 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 == NaN
false
> pippo === NaN
false
``````

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

``````> pippo == pippo
false
> pippo === pippo
false
> NaN == NaN
false
> NaN === NaN
false
``````

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)
> 0
parseInt(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!
``````