NaN, isNaN() & Number.isNaN()
Tags: javascript, es6, fundamentals
Published: 2020-08-23 14:45:09

---
title: NaN, isNaN() & Number.isNaN()
published: true
description: In this article I talk about the quirks of the the NaN special value, and why we should use the Number.isNaN() utility instead of isNaN().
tags: JavaScript, ES6, fundamentals
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/pyulnxc2jwl6z5sfb62u.png
---

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:

```javascript
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.

```javascript
const x = 10 / "foo"  // This will evaluate to NaN

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

NaN !== NaN  // true

```

### **Checking if a value is `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:

```javascript
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:

```javascript
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 <a href="https://caniuse.com/#search=Number.isNaN" target="_blank">Can I Use: Number.isNaN</a>.


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

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

```javascript
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:

```javascript
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.

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

If you want to learn more about <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" target="_blank">Object.is</a> you can go to this MDN <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" target="_blank">link</a>.