How to Check if NaN is equal to NaN 🤔
JS has a quirk where NaN is the only value that is NEVER equal to itself 🤨. So how do we test for it? Finally, ES6 introduced a new method that solves this issue with
const item = NaN; // Huh?? this doesn't work item === NaN; // false // Yay, this works! Object.is(item, NaN); // true
When would you want to check for NaN?
Ex 1: When trying to do a mathematical calculation
A common example is to check if a value is divisible. In this example, you can't compare it to
NaN since that comparison would always fail.
const isDivisible = 5 / "Some String"; isDivisible // returns NaN isDivisible === NaN // returns false if (isDivisible === NaN) // ❌ so this statement would never work since this will always return false because NaN is never equal to NaN.
Ex 2: When trying to extract a number from a string
Again, if you try to test
NaN in your
if statement, it won't work because the condition will always return false.
const hasNumber = parseInt("Hello"); hasNumber // returns NaN hasNumber === NaN // returns false if(hasNumber === NaN) // ❌ again, you won’t be able to use this logic because this will always return false.
isNaN you ask?
isNaN is actually not the best way to check
Kyle Simpson from "You Don't know JS" provided a really good explanation.
Here is an excerpt from his book:
The isNaN(..) utility has a fatal flaw. It appears it tried to take the meaning of NaN ("Not a Number") too literally -- that its job is basically: "test if the thing passed in is either not a number or is a number." But that's not quite accurate.
var a = 2 / "foo"; var b = "foo"; a; // NaN b; // "foo" window.isNaN( a ); // true window.isNaN( b ); // true -- ouch!
Clearly, "foo" is literally not a number, but it's definitely not the NaN value either! This bug has been in JS since the very beginning (over 19 years of ouch).
Alternatively you can also use
Number.isNaN to check.
const item = NaN; Object.is(item, NaN); // true Number.isNaN(item); // true
Use Number.isNaN to check NaN instead of
[email protected]eyalPerry: I think that
Number.isNaN is better suited for this use, as it does not incur the overhead of checking the parameters against various types and their edge cases.
Object.is also works for comparing object and function instances, comparing strings by value, boolean values and more (all of this is on MDN). This means that under the hood, it has to do some type checking in order to properly work. This makes it a sort of a multitool. Sometimes- multitools are good. But if you are only looking to check whether a value is Nan or not- there's no point in paying the price for Object.is. Also, personally- I like using the most accurate and exact way in any scenario. In this case-
Number.isNaN is exactly that. Note: beware of the global
isNaN function, do not use it
More information on
@RanqueBenoit pointed out some funky traits of
const notNumber = 3 * "str"; notNumber // NaN typeof notNumber // number 🤨 isNaN(notNumber) // true 🤨
NaN is not equal to
For those curious about the "why" of this. Here's a medium post explaining why
NaN is not equal to
Short Story: According to IEEE 754 specifications any operation performed on NaN values should yield a false value or should raise an error.
Thanks CJ J for sharing this. TL;DR is "Because the IEEE standard says so".