Is Number.IsNaN() more broken than isNaN()

JavascriptNanEcmascript 6

Javascript Problem Overview


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...

enter image description here

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?

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

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')

Solution 3 - Javascript

The key difference between the two is that the global isNaN(x) function performs a conversion of the parameter x to a number. So

isNaN("blabla") === true

because Number("blabla") results in NaN

There are two definitions of "not a number" here and that's perhaps where the confusion lies. Number.isNaN(x) only returns true for the IEEE 754 floating point specification's definition of Not a Number, for example:

Number.isNaN(Math.sqrt(-1))

as opposed to determining whether the object being passed in is of numeric type or not. Some ways of doing that are:

typeof x === "number"
x === +x
Object.prototype.toString.call(x) === "[object Number]"

Solution 4 - Javascript

As mentioned in a comment isNaN() and Number.isNaN() both check that the value you pass in is not equal to the value NaN. The key here is that NaN is an actual value and not an evaluated result e.g. "blabla" is a String and the value is "blabla" which means it is not the value "NaN".

A plausible solution would be doing something like:

Number.isNaN(Number("blabla")); //returns true.

Solution 5 - Javascript

Basically, window.isNaN performs a type conversion to a number, then checks if it is NaN. Whereas, Number.isNaN doesn't try to convert its argument to a number. So basically, you can think of window.isNaN, and Number.isNaN as working like so.

window.isNaN = function(n){
    return Number(n) !== Number(n);
}

window.Number.isNaN = function(n){
    return n !== n;
}

Please note that you don't need actually to use the window. to call isNaN or Number.isNaN. Rather, I am just using it to provide a better distinction between the two similarly-named methods to try to cut down on confusion.

~ Happy Coding!

Solution 6 - Javascript

Per, MDN, it (NaN) is the returned value when Math functions fail and as such it is a specific value. Perhaps a better name would have been, MathFunctionFailed.

To determine if something is a number requires parsing which fails nicely over a broad range of non numeric inputs, successfully detecting numbers and strings representing numbers, hence:

function isNumber(v) {return Number.isNaN(parseFloat(v)); }

Solution 7 - Javascript

The following works because NaN is the only value in javascript which is not equal to itself.

Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

Solution 8 - Javascript

I use a simple workaround to check Number.isNaN():

    let value = 'test';
    Number.isNaN(-value); // true
    value = 42;
    Number.isNaN(-value); // false

js trying to convert the value to the negative Number, if the conversion is failed - we have NaN.

Simple, isn't it?

Moreover, online benchmark tests say Number.isNaN is lighter than isNaN.

Solution 9 - Javascript

Number.isNaN(x) checks if x is directly evaluated to NaN or not.

RAWR is not the same as NaN. Think of NaN as an entity to represent the result of some mathematical calculation where the computer does not know how to represent the number.

A mathematical operation is not going to yield a non-numeric result, hence the typeof NaN is number.

The string RAWR had undergone no mathematical operation to yield NaN. However, if you were to call Number.isNaN(+'RAWR'), it would result in NaN since the unary + operator is trying to convert 'RAWR' to a number.

On the other hand, isNaN(y) tells whether y can be converted to a number or not. If isNaN(y) is false, y can be converted to a number. But if isNaN(y) is true, y can not be converted to a number.

So a good rule of thumb is:

  1. Do I want to check if x can be successfully converted to a number? Use isNaN(x) == false in that case. Unsuccessful conversion results in NaN.
  2. Do I want to check if x is evaluated to NaN? Use Number.isNaN(x) == true for that.

Solution 10 - Javascript

1. Number.isNaN

alert(Number.isNaN('Hello')); // false 

Shouldn't it return true because Hello is a string and its Not A Number right ? But Lets know why it returns false.

MDN docs says :

> true if the given value is NaN and its type is Number; otherwise, > false.

Yes Hello value is NaN but the type is string , you can check the type as follows:

alert(typeof `Hello`);  // string

Usage:

Use when you want to check the value is both NaN and type is number.

2. isNaN

alert(isNaN('Hello')); // true

MDN docs says:

> true if the given value is NaN; otherwise, false.

Usage:

Use when you want to check value is just NaN.

3. jQuery.isNumeric()

Jquery Docs Says :

> Determines whether its argument represents a JavaScript number.

alert($.isNumeric('Hello')); // false
alert($.isNumeric(3)); //true

Usage:

Use when you want to check value is a number or can be converted to a number.

Reference

Solution 11 - Javascript

@phill, as stated in other responses, neither is broken.

Number.isNaN work on a number or instance of Number, so even Number.isNaN(new Date(NaN)) is false.

isNaN, on the other hand, is generic and tries to convert its parameter to a number before checking it.

If you want to determine if a value is (or contains) NaN, you can use this function:

function valueIsNaN(value) {
  // eslint-disable-next-line no-self-compare
  return value !== value || typeof value == 'object' && Number.isNaN(value.valueOf());
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPhillView Question on Stackoverflow
Solution 1 - JavascriptBoltClockView Answer on Stackoverflow
Solution 2 - JavascriptJLRisheView Answer on Stackoverflow
Solution 3 - JavascriptTom FenechView Answer on Stackoverflow
Solution 4 - JavascriptkaspermoerchView Answer on Stackoverflow
Solution 5 - JavascriptJack GView Answer on Stackoverflow
Solution 6 - JavascriptGeorgeView Answer on Stackoverflow
Solution 7 - Javascriptsendon1982View Answer on Stackoverflow
Solution 8 - JavascriptOlexandrView Answer on Stackoverflow
Solution 9 - JavascriptacagastyaView Answer on Stackoverflow
Solution 10 - JavascriptShaiju TView Answer on Stackoverflow
Solution 11 - JavascriptaMarCruzView Answer on Stackoverflow