## DEV Community is a community of 700,142 amazing developers

We're a place where coders share, stay up-to-date and grow their careers. # NaN, isNaN() & Number.isNaN()

The number type has several special values, and one of them is NaN.

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"

x === NaN    // false
x == NaN     // false

NaN !== NaN  // true

``````

### Checking if a value is `NaN`

There are two methods that can help us testing 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 = Math.sqrt(-1)
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"
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.

However, it has a 94.06% global support, so nothing to worry about here. IE doesn't support it, but it is almost gone anyway.

### 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
``````