The 3 ways you can check for NaN in JavaScript (and 2 you can't!)
Tags: javascript, beginners
Published: 2021-10-25 14:14:43

**NaN isn't something you will often (if ever) write into your code. But it can crop up from time to time. And when it does, you can't check for it in the same way you could check for other values. Because NaN does not equal NaN. Are you confused? Don't be! Let's get to know NaN.**

`NaN` is an awkward member of the JavaScript family. We spend most of our time avoiding it, and when we do meet `NaN`, we can't get away quick enough! `NaN` is often misunderstood. It doesn't even understand itself. If you ask, "Hey `NaN` are you a `NaN`?" nearly half the time, it will say no!

```javascript
let x = NaN;
// 2 ways that don't work
console.log( x === NaN); // false
console.log( x == NaN); // false
// 3 ways that do work
console.log(Number.isNaN(x)); // true
console.log(Object.is(x, NaN)); // true
console.log(x !== x); // true
```

If you are confused about why some of these ways of checking for `NaN` don't work, and why some do, you're not alone! Because the `===` operator is the way we usually check for equality, and when `NaN` gets involved, it messes everything up. So why is `NaN` so troublesome? And what can we do about it?

`NaN` can happen for a wide range of reasons, usually if you try to do a calculation that JavaScript considers to be invalid math. Maybe you did `0 / 0`. And once it happens and `NaN` appears, it messes up all your future calculations. Not cool, `NaN`. 

So let's say you have a number, `x`, and you want to check that it's valid. You need to know nothing has gone wrong in your code that's turned your number into not-a-number. So how can you avoid the dreaded `NaN`?

For the rest of this post, `x` is `NaN`. That's right - your number is not a number. And we need to write some simple code to detect it. So let's start by pointing the variable `x` to `NaN`.

```javascript
let x = NaN;
```

Ok, now we can begin.

## Ways you can't check for NaN

1. `x === NaN`
2. `x == NaN`

### Strict Equality

If you know a little JavaScript, you might bring out the old trusted **strict equality** operator. And this is the go-to operator for checking equality - it even says it in the name. So, of course, this *should* work. 

```javascript
console.log(x === NaN); // false
```

Hmmm. That didn't work. Maybe my number is a number after all. Let's see what's going on here.

```javascript
console.log(NaN === NaN); // false (WTF??)
```

So, as it turns out, `NaN` does not equal `NaN`. At least not strictly. 

### Loose equality

I still use **loose equality** `==` from time to time, although it's frowned upon (and sometimes banned in some codebases) because the results can be unexpected. But can it check for `NaN`? 

```javascript
console.log(x == NaN); // false
console.log(NaN == NaN); // false (WTF again!!)
```

At this point, I thought maybe equality with `NaN` might work in the same way as an object, and each time you write it, you create a new `NaN`. But I know that NaN is a primitive value, so that's not true either.

```javascript
// objects don't equal each other
console.log({} === {}); // false
console.log({} == {}); // false
// but two variables can point to the same object
let myObject = {};
let sameObject = myObject;
console.log(myObject === sameObject); // true

// but that's not how NaN works either
let myNaN = NaN;
let sameNaN = myNaN;
console.log(myNaN === sameNaN); // false
```

Eugh, infuriating! `NaN` is its own thing, and we will never be able to check for equality like this. You could call it a bug, or you could call it a feature. Either way, we need to accept it for what it is and move on. So let's look at three ways you can check for `NaN` (way number 3 is super cool once you get your head around it).

## Ways you can check for NaN

So `NaN` is a number, but it's a special type of number, that's for sure. Because its **NOT A NUMBER!**. Although the two most obvious ways to check for a value don't work with `NaN`, there are three pretty cool ways that do work.

1. `Number.isNaN(x)`
2. `Object.is(x, NaN)`
3. `x !== x`

### Ask a number if it's not a number

Ok, so I mentioned that `NaN` is a type of number.

```javascript
console.log(typeof NaN); // 'number'
```

And for that reason, there's a method on the Number constructor specifically for checking NaN. `Number.isNaN()`. That's right - you can ask a number if it's a number!

```javascript
console.log(Number.isNaN(x)); // true
```

### Object.is(x, NaN)

The [`Object.is()` method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) checks if two values are the same value. Unlike strict equality, it works with `NaN`.

```javascript
console.log(Object.is(x, x)); // true
console.log(Object.is(x, NaN)); // true
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(NaN, Number.NaN)); // true
```

### Strict inequality

Remember how I said that strict *equality* is one of the two ways you can't check for `NaN`? Well, if you tweak your thinking slightly and check for *inequality* instead, you can.

This way is my personal favourite. I almost see it as a way of tricking `NaN` into revealing itself. Since `NaN !== NaN`, and it's kinda weird, we can use that logic to check for `NaN`.

```javascript
console.log(x !== x); // true
```

If you know that `x` should be a number, and you run `x !== x` and get true, you know you have found `NaN`.

And the reverse is true too. Say you want to validate that you have a valid number in your code, you can do `if (myNumber === myNumber)` because if the number doesn't equal itself, it's in denial about who it is. There's not only one type of number that's in that kind of denial, and you can be sure it's not a number (`NaN`). 

---

And that's it, the three ways you can check for `NaN` in Javascript, and the two ways you cant. Hopefully, you find `NaN` a little less confusing now and a lot more interesting!