What is NaN?
What causes values to become NaN?
Values can become NaN through a variety of means, which usually involve erroneous math calculations (such as 0/0), or as a result of type coercion, either implicit or explicit. A common example is when you run parseInt on a string that starts with an alphabetical character. This isn’t exclusive to parseInt, as it also applies when using explicit coercion with Number(), or with the unary “+” operator.
How do you check for NaN?
Before selecting a method for checking for NaN, how should you not check for NaN?
For example, if parseInt(“a”) returns NaN, then parseInt(“a”) === NaN will return false. This may seem strange, but it makes perfect sense after thinking about what NaN really is.
NaN doesn’t tell you what something is, it tells you what it isn’t.
These two different strings being passed to parseInt() will both return NaN.
parseInt(“abc”) // NaN parseInt(“def”) // NaN
Here are a few examples of strict inequality comparisons, which demonstrate the inconsistency of NaN.
2 !== 2 // false true !== true // false “abc” !== “abc” // false ... NaN !== NaN // true
Method 1: isNaN or Number.isNaN
The difference between isNaN and Number.isNaN is that isNaN coerces the argument into a number type. To avoid complicated and unexpected outcomes, it is often advised to use the newer, more robust Number.isNaN to avoid these side effects. Number.isNaN does not perform any forcible type conversion, so it simply returns the boolean based on the parameter.
Here is an example of the difference between the two methods:
isNaN(undefined) // true Number.isNaN(undefined) // false
isNaN, when passed undefined, returns true because undefined becomes NaN after number coercion. You can test this yourself by running Number(undefined). You will find that it returns NaN.
Number.isNaN, on the other hand, returns false. This is because no coercion takes place, and undefined is not NaN, it is simply undefined.
Method 2: Object.is
Object.is(0, -0) will return false, while 0 === -0 will return true. Comparisons of 0 and -0 differ, as do comparisons of NaN. This concept is called “Same-value-zero equality.”
NaN === NaN // false Object.is(NaN, NaN) // true
Object.is(NaN, NaN) will in fact return true, while we already know that NaN === NaN returns false. That makes this yet another valid way to check if something is not a number.
Between the given methods of checking for NaN, the most common is to use the global isNaN function, or the ES2015 Number.isNaN method. While method #2 is valid, most people will typically use isNaN or Number.isNaN, which were created specifically for checking for NaN.