BlogJavaScript

The 3 ways you can check for NaN in JavaScript (and 2 you can't!)

Written by Codemzy on October 25th, 2021

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!

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.

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.

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.

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?

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.

// 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.

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!

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

Object.is(x, NaN)

The Object.is() method checks if two values are the same value. Unlike strict equality, it works with NaN.

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.

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!