I have a confusion in how NaN works. I have executed isNaN(undefined)
it returned true
. But if I will use Number.isNaN(undefined)
it is returning false
.
So which one I should use? Also why there is so discrepancy in the result?
I have a confusion in how NaN works. I have executed isNaN(undefined)
it returned true
. But if I will use Number.isNaN(undefined)
it is returning false
.
So which one I should use? Also why there is so discrepancy in the result?
To quote from a ponyfoo article on numbers in ES6:
Number.isNaN is almost identical to ES5 global isNaN method. Number.isNaN returns whether the provided value equals NaN. This is a very different question from “is this not a number?”.
So isNaN
just checks whether the passed value is not a number or cannot be converted into a Number. Number.isNaN
on the other hand only checks if the value is equal to NaN
(it uses a different algorithm than ===
though).
The String 'ponyfoo'
for example is not a number and cannot be converted into a number, but it is not NaN
.
Example:
Number.isNaN({});
// <- false, {} is not NaN
Number.isNaN('ponyfoo')
// <- false, 'ponyfoo' is not NaN
Number.isNaN(NaN)
// <- true, NaN is NaN
Number.isNaN('pony'/'foo')
// <- true, 'pony'/'foo' is NaN, NaN is NaN
isNaN({});
// <- true, {} is not a number
isNaN('ponyfoo')
// <- true, 'ponyfoo' is not a number
isNaN(NaN)
// <- true, NaN is not a number
isNaN('pony'/'foo')
// <- true, 'pony'/'foo' is NaN, NaN is not a number
isNaN
converts the argument to a Number
and returns true if the resulting value is NaN
.Number.isNaN
does not convert the argument; it returns true when the argument is a Number
and is NaN
.So which one i should use.
I am guessing you are trying to check if the value is something that looks like a number. In which case the answer is neither. These functions check if the value is an IEEE-754 Not A Number. Period. For example this is clearly wrong:
var your_age = "";
// user forgot to put in their age
if (isNaN(your_age)) {
alert("Age is invalid. Please enter a valid number.");
} else {
alert("Your age is " + your_age + ".");
}
// alerts "Your age is ."
// same result when you use Number.isNaN above
Also why there is so discrepancy in the result.
As explained above Number.isNaN
will return false immediately if the argument is not a Number
while isNaN
first converts the value to a Number
. This changes the result. Some examples:
| Number.isNaN() | isNaN()
----------------+----------------------------+-----------------------
value | value is a Number | result | Number(value) | result
----------------+-------------------+--------+---------------+-------
undefined | false | false | NaN | true
{} | false | false | NaN | true
"blabla" | false | false | NaN | true
new Date("!") | false | false | NaN | true
new Number(0/0) | false | false | NaN | true
I found that if you want to check if something is numbery (or not), then a combination of Number.isNaN()
with either Number.parseInt()
or Number.parseFloat()
(depending on what you expect) to cover most use cases:
consider: test a bunch of different input vars against several is number tests:
r = [NaN, undefined, null, false, true, {}, [], '', ' ', 0, 1, '0', '1']
.map(function(v){return [
v,
isNaN(v),
Number.isNaN(v),
Number.isInteger(v),
Number.parseInt(v, 10),
Number.isNaN( Number.parseInt(v, 10))
];});
console.table(r);
// or if console.table() not available:
r.join('\n', function(v){v.join(',')} );
result:
NaN , true , true , false, NaN, true
undefined, true , false, false, NaN, true
null , false, false, false, NaN, true
false , false, false, false, NaN, true
true , false, false, false, NaN, true
Object , true , false, false, NaN, true
Array(0) , false, false, false, NaN, true
'' , false, false, false, NaN, true
' ' , false, false, false, NaN, true
0 , false, false, true , 0 , false
1 , false, false, true , 1 , false
'0' , false, false, false, 0 , false
'1' , false, false, false, 1 , false
Note the last column, which is usually what I want in my experience.
In shortly,
isNaN()
will check if the convert of value to Number (type) are failed
For example'abc'
Number.isNaN()
will check if the given value type is Number but not valid number
For example: 'bb'/33
First, forget about the useless meaning of the value NaN
, just treat it as bad number
. As soon as you saw NaN
, read it as 'bad number'.
Number.isNaN
is a more safe and robust version of isNaN
, isNaN
has a bug,
isNaN(NaN) // true, this is the supposed result, the argument is NaN
isNaN('hello') // true, but this is misleading, cuz `hello` is not NaN
isNaN
can't distinguish NaN
with other not-number values, such as characters.
So a new method comes into play.
Number.isNaN checks if the value is number firstly, if it is not a number, it returns false immediately.
Number.isNaN('hello') // false, 'hello' is not NaN, this is the supposed result
Number.isNaN()
This method returns true if the value is of the type Number, and equates to NaN. Otherwise it returns false. e.g.
Number.isNaN(123) //false
Type of 123 is number but 123 is not equal to NaN, therefore it returns false.
Number.isNaN('123') //false
Type of 123 is string & '123' is not equal to NaN, therefore it returns false.
Number.isNaN(NaN) //true
Type of NaN is number & NaN is equal to NaN, therefore it returns true.
Number.isNaN('NaN') //false
Type of 'NaN' is string & 'NaN' is not equal to NaN, therefore it returns false.
global isNaN() function
The global isNaN() function converts the tested value to a Number, then tests it.
isNaN(123) //false
isNaN('123') //false
isNaN(NaN) //true
isNaN('NaN') //true
As a definition, NaN
is a Number but not a valid one.
So, to be able to use Number.isNaN
correctly, convert the tested value to a number + (value) and then pass it to Number.isNaN.
But, with isNaN
, you don't have to do that, it will just check it it's not a number (not if it's an invalid number).
Example : want to check whether "a155" is not a number (NaN):
Number.isNaN("a125") //false
isNaN("a125") // true
Now :
Number.isNaN(+("a125")) //true
© 2022 - 2025 — McMap. All rights reserved.
Due to both equality operators, == and ===, evaluating to false when checking if NaN is NaN, the function Number.isNaN() has become necessary. In comparison to the global isNaN() function, Number.isNaN() doesn't suffer the problem of forcefully converting the parameter to a number. This means it is now safe to pass values that would normally convert to NaN, but aren't actually the same value as NaN. This also means that only values of the type number, that are also NaN, return true.
– Devisor