Does NaN actually means Not-a-Number?
Tags: javascript, programming, react, reactnative
Published: 2023-05-24 18:07:22

Consider we have the following mathematical operation to perform:

```
var a =  13 / "bar"; 

console.log(a); // NaN
```

Any mathematical operation we perform without both operands being numbers, results in the operation failing to produce a valid number which we call as **NaN**.

From the above operation, a is NaN and if we do:

```
console.log(typeof a === "number") // true
```
Surprised??

If NaN means not-a-number, then why **typeof NaN is number**?

Confusing isn't it?

Let's talk more about What exactly does NaN means?

It isn't quite accurate to think of NaN as "not a number". Rather, it is more accurate to think of it as being an "invalid number", "failed number", or even "bad number".

NaN is a kind of "sentinel value" that represents a special kind of error condition within the number set. We can think of it like: "**Hey, I tried to perform a mathematic operation but failed, so here's the failed number result instead**".

Now if we have some value in a variable and we want to test and see if it's this special failed number NaN,  how will we do it?

One thing which will first come in our mind is to use the comparison operators and using those, we can **compare the variable with the NaN itself**. 

Simple isn't it? Let see....

```
var a =  13 / "bar";

console.log(a == NaN) // false
console.log(a === NaN) // false
```

More confusion isn't it? Lets understand a bit more about NaN.

NaN is a very special value in that it's never equal to another NaN value.(i.e. it's never equal to itself).

So even if we do below:

```
console.log(a == a) // false
console.log(a === a) // false
```

The results in both cases is going to be false. **NaN is the only value in the whole language where NaN isn't equal to itself**.

Now the question arises, how do we test for it if we can't compare NaN?

For this, we use a built-in global utility function called isNaN(...).

```
var a =  13 / "bar";

console.log(isNaN(a)) // true
```

Simple enough right?

Actually, this isNaN(...) has a fatal flaw. It appears that it takes meaning of NaN as Not-a-Number too literally.

See the below example:

```
var a =  13 / "bar";
var b = "foo";

console.log(isNaN(a)) // true
console.log(isNaN(b)) // true
```

From the example above, it is just checking "if the thing passed in is either a number or not a number". 

Clearly, "foo" is literally not a number, but it's definitely not the NaN value either. This is the bug in JS since very beginning.

As of ES6, finally a replacement utility has been provided: Number.isNaN(...) which solves the above problem.

Simple Polyfill for this for checking the NaN values in pre-ES6 browsers is:

```
if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return(
            typeof n === 'number' && isNaN(n)
        );
    }
}
```

We can implement this Polyfill in an easy way by taking advantage of the fact that NaN isn't equal to itself.

```
if (!Number.isNaN) {
    Number.isNaN = function(n) {
        return n !== n;
    }
}
```

If you're currently using just isNaN(...) in a program, the sad reality is your program has a bug, even if you haven't been bitten by it yet. So now is the really good idea to use reliable test, like Number.isNaN(...) as provided.

That is all for the topic. Hope you like it.

Reference: You Don't know JS by Kyle Simpson