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 returnstrue
if the resulting value isNaN
; Number.isNaN()
returnstrue
if and only if the argument is of typeNumber
and the value equals toNaN
.
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.