What's the Difference Between isNaN() and Number.isNaN() in JavaScript?

The isNaN() (global function) and Number.isNaN() (method on Number object) are both meant for checking if the argument supplied (to either function) is equal to the value NaN (which represents "Not-a-Number"):

isNaN(NaN); // true
isNaN(Number.NaN); // true
// ES6+
Number.isNaN(NaN); // true
Number.isNaN(Number.NaN); // true

The term "not a number" can be confusing, as it might come across as a means to check whether a non-numeric value is a number or not. However, this is not the case as both, isNaN() and Number.isNaN() are meant to check if a value equals to the special numeric value "NaN" (as defined in the IEEE-754 standard). If you want to check whether a value is a number or not, you should use typeof value === 'number' instead.

The need for isNaN() or Number.isNaN() arises from the fact that NaN never equals to any other number, or even to itself:

NaN === NaN; // false

However, both isNaN() and Number.isNaN(), differ in terms of how they check if a value is NaN:

  • Global isNaN() function first converts the argument to a number, and then returns true if the resulting value is NaN;
  • Number.isNaN() returns true if and only if the argument is of type Number and the value equals to NaN.

The way the global isNaN() function converts the argument to a number first, leads to unexpected results (as you can see in the table below):

x Number(x) isNaN(x)
undefined NaN true
{} NaN true
'foo' NaN true
new Date('') NaN true
new Number(0/0) NaN true

As you can see in the table above, isNaN() unexpectedly returns true for values that are clearly not NaN, but are rather coerced into NaN. For this reason, it is better to use Number.isNaN(), which only returns true if the value is in fact a Number and equals to NaN.

x typeof x === 'number' Number.isNaN(x)
undefined false false
{} false false
'foo' false false
new Date('') false false
new Number(0/0) false false

Please note that Number.inNaN() was introduced in ES6. If you're unable to support a minimum ES6, then you can either use a polyfill or fallback to isNaN() with some additional checks.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.