The **number type** has several special values, and one of them is **NaN**, which is a special value in JavaScript representing a computational error in numeric operations.

In this article I am going to share some of the things we need to be aware of when working with this special value.

I suggest you try the code snippets as you find them along the article.

###
**The naming is confusing**

Let's do a `typeof`

on `NaN`

to see what it returns:

```
typeof NaN // "number"
```

As you can see it returns "number" as the type, so it clearly means that `NaN`

is actually a `number`

... wait a second, what!? ðŸ˜®

So, it would have been better to name this special value something like: **"Not a Valid Number"** or similar, in order to avoid the confusion.

The `NaN`

special value represents some sort of error in the `number`

set. It is returned when we try to do a mathematic operation and it fails. So, In this case, the `NaN`

special value is returned.

###
**The equality quirk**

If we want to check if some value stored in a variable is `NaN`

, using either the `===`

or the `==`

operators won't work since `NaN`

is the only value that is not equal to itself.

```
const x = 10 / "foo" // This will evaluate to NaN
x === NaN // false
x == NaN // false
NaN !== NaN // true
```

###
**Checking if a value is **`NaN`

`NaN`

There are two methods that can help us test if a value is `NaN`

. We can use either the built-in global utility method `isNaN()`

or the `Number.isNaN()`

utility. But you will see bellow why is recommended to always use `Number.isNaN()`

instead of `isNaN()`

. Let's try them out:

```
const y = "foo" * 10 // This will evaluate to NaN
const z = "bar"
isNaN(y) // true
isNaN(z) // true
isNaN(20) // false
isNaN("55")// false
```

It seems that the `isNaN()`

utility is taking the `NaN`

literally as **Not a Number**.

Let's thinkg about it for a moment... ðŸ¤”

It seems the `isNaN()`

logic is somethimg like this:

"If the value passed is (or evaluates to) either the special value `NaN`

or something that is not of the type `number`

( `typeof x !== "number"`

), then return `true`

"

However, this is clearly not accurate, because, as far as we know `typeof NaN === "number"`

, so it should return `true`

only if we pass something that is (or evaluates to) the special value `NaN`

, and it should return `false`

if the value is not of type of number.

Let me elaborate a bit more on this.

The logic should be instead something like this:

"If the value passed is literally the value `NaN`

return `true`

, otherwise return `false`

".

Fortunately, there's a utility method (a replacement of `isNaN`

) that does exactly that:

```
const a = 20 / "foo" // This will evaluate to NaN
const b = "bar"
const c = 35
const d = {}
Number.isNaN(a) // true
Number.isNaN(b) // false
Number.isNaN(c) // false
Number.isNaN(d) // false
```

If you want to check the browser support for this built-in utility method, you can go to Can I Use: Number.isNaN.

###
**A couple of polyfills for Number.isNaN**

Writing these polyfills will help us understand these utilities a bit more.

```
if(!Number.isNaN) {
Number.isNaN = function(n) {
if( typeof n === "number" ) {
return window.isNaN(n)
}
return false
}
}
```

So in this one, we filter the value and make sure it has the type of `number`

, if so we use the `isNaN`

utility.

But we can use an even simpler solution, considering the fact that `NaN`

is not equal to itself. Let's see:

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

###
**Extra**

We can also use the `Object.is()`

method to check if two values are the same. It is helpfull because it covers even the corner cases like `-0 === 0 // true`

(which should be `false`

in this particular case) and it covers the `NaN`

equality quirk as well.

```
Object.is(NaN, NaN) // true
```

If you want to learn more about Object.is you can go to this MDN link.

## Top comments (2)

Wow nice, I really liked it keep it up.ðŸ”¥

Thanks man, glad you liked it! Cheers!