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
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.
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
Number
and returns true if the resulting value is NaN
.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
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