The Safest Way to Test for NaN

Hero image for The Safest Way to Test for NaN. Image by Mick Haupt.
Hero image for 'The Safest Way to Test for NaN.' Image by Mick Haupt.

A NaN or Not a Number is an unusual thing in JavaScript development and often presents itself as a spanner in the works for new developers when first working with numbers or equations. Typically it comes up when a variable unexpectedly returns a string or a boolean (rather than a number), whilst your code attempts to do calculations with it. We've all encountered NaN before, and it can prove to be a bit of a nightmare when it comes up unexpectedly.

In code safeguarding practices, it is worth being able to test against any essential data source. There are a few ways to test for NaN, but even the common methods to test it have some surprising quirks.


Don't compare against NaN

I will often find a team member I'm mentoring who will already have tried this if they come across this problem. The thought process is sound: we should simply check the variable against NaN, in exactly the same way we can for undefined or null, right?

Unfortunately, that doesn't work; comparing NaN to NaN always returns false:

const nonNumber = 1 * 'this is a string';// both of these are 'false'nonNumber == NaN;nonNumber === NaN;

This is because even though NaN is not a number, it may not always be the same notnumber...


Don't use typeof

As if not being able to do a hard check wasn't baffling enough, the next option should be to check typeof which also will not work. In JavaScript (and other computing languages), NaN is still recognised as a number:

const nonNumber = 1 * 'this is a string';// this will return 'number'typeof nonNumber;

Briefly: although NaN is quite literally not a number, it is still a number type by inflexion.


isNan()

Perhaps less wellknown than it deserves, the isNan() global object method will do the trick. However, it comes with the caveat that it will return true for anything that isn't a number:

const nonNumber = 1 * 'this is a string';// this will return 'true'isNan(nonNumber);const aString = 'this is not a number either';// this will also return 'true'isNan(aString);

The Solution: Number.isNan()

For the most robust and foolproof solution, we can expand on the above by checking whether or not the type of the variable is a number, and then run it through .isNan() at the same time. It's a little bit counterintuitive to think about, but it works:

const nonNumber = 1 * 'this is a string';// this will return 'true'Number.isNan(nonNumber);const yourString = 'this is not a number either';// this will return 'false'Number.isNan(yourString);

As a concept, NaN is a bit of an outlier; it can be difficult and frustrating when building complex pricing matrices or calculators as a mishap any step of the way will result in a NaN result. The Number.isNan() solution is the best way to deal with incorrect values and allows you to handle them gracefully although it only works for ES6compatible browsers. 

There is a workaround for legacy and noncompatible browsers, which is to perform a check where you compare the variable against itself. This works because NaN is the only value that doesn't equal itself (as we touched on earlier).


Categories:

  1. ES6
  2. Front‑End Development
  3. Guides
  4. JavaScript
  5. Testing