Soooooo isNaN
is apparently broken in JavaScript, with things like:
isNaN('') isNaN(' ') isNaN(true) isNaN(false) isNaN([0])
Returning false, when they appear to all be... Not a Number...
In ECMAScript 6, the draft includes a new Number.isNaN
but it looks like (imo) that this is also broken...
I would expect
Number.isNaN('RAWRRR')
To return true, since it's a string, and cannot be converted to a number... However...
It seems that things that I would consider... not a number, are indeed, not, not a number...
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-isfinite-number
The examples on MDN say:
Number.isNaN("blabla"); // e.g. this would have been true with isNaN
I don't understand how this is "More robust version of the original global isNaN." when I cannot check to see if things are not a number.
This would mean we're still subjected to doing actual type checking as well as checking isNaN... which seems silly...
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-isnan-number
The ES3 draft here basically says, everything is always false, except with its Number.NaN
Does anyone else find this is broken or am I just not understanding the point of isNaN?
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 .
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 .
isNaN() returns true if a number is Not-a-Number. In other words: isNaN() converts the value to a number before testing it.
isNaN()
and Number.isNaN()
both test if a value is (or, in the case of isNaN()
, can be converted to a number-type value that represents) the NaN
value. In other words, "NaN" does not simply mean "this value is not a number", it specifically means "this value is a numeric Not-a-Number value according to IEEE-754".
The reason all your tests above return false is because all of the given values can be converted to a numeric value that is not NaN
:
Number('') // 0 Number(' ') // 0 Number(true) // 1 Number(false) // 0 Number([0]) // 0
The reason isNaN()
is "broken" is because, ostensibly, type conversions aren't supposed to happen when testing values. That is the issue Number.isNaN()
is designed to address. In particular, Number.isNaN()
will only attempt to compare a value to NaN
if the value is a number-type value. Any other type will return false, even if they are literally "not a number", because the type of the value NaN
is number. See the respective MDN docs for isNaN()
and Number.isNaN()
.
If you simply want to determine whether or not a value is of the number type, even if that value is NaN
, use typeof
instead:
typeof 'RAWRRR' === 'number' // false
No, the original isNaN
is broken. You are not understanding the point of isNaN
.
The purpose of both of these functions is to determine whether or not something has the value NaN
. This is provided because something === NaN
will always be false
and therefore can't be used to test this. (side note: something !== something
is actually a reliable, although counter-intuitive, test for NaN
)
The reason isNaN
is broken is that it can return true
in cases when a value is not actually NaN
. This is because it first coerces the value to a number.
So
isNaN("hello")
is true
, even though "hello"
is not NaN
.
If you want to check whether a value actually is a finite number, you can use:
Number.isFinite(value)
If you want to test whether a value is a finite number or a string representation of one, you can use:
Number.isFinite(value) || (Number.isFinite(Number(value)) && typeof value === 'string')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With