tags:

views:

1887

answers:

8
+2  A: 

Null is not NaN, as well as a string is not NaN. isNaN() just test if you really have the NaN object.

gizmo
But then at least a string is cast into a NaN object, as isNaN("text") returns true.
Hanno Fietz
+4  A: 

isNaN looks for numeric values that are not numbers - things like infinity, undeflow etc.; you could think of them as error codes for calculations. null is not one of these.

More information here.

moonshadow
Infinity is not NaN. The only numerical expression I can think of that produces NaN is 0/0.
Ryono
A: 

I'm not exactly sure when it comes to JS but I've seen similar things in other languages and it's usually because the function is only checking whether null is exactly equal to NaN (i.e. null === NaN would be false). In other words it's not that it thinks that null is in fact a number, but it's rather that null is not NaN. This is probably because both are represented differently in JS so that they won't be exactly equal, in the same way that 9 !== '9'.

Jason Tennier
+17  A: 

Here's the definitive answer:

The function isNaN attempts to convert the passed parameter to a number. If the parameter can't be converted, it returns true; otherwise, it returns false.

So in your case, null is converted to the number 0. (Try evaluating 'Number(null)' and see that it returns 0.) Then 0 is evaluated as being a number and isNaN returns false. A string that is only digits can be converted to a number and isNaN also returns false. A string that cannot be converted to a number will cause isNaN to return true.

In addition to these apparent edge cases are the standard numerical reasons for returning NaN like 0/0.

Original Source

Ryono
+2  A: 

This is indeed disturbing. Here is an array of values that I tested:

var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]

It evaluates (in the Firebug console) to:

,NaN,blah,NaN,,0,0,1,Infinity,-Infinity,5

When I call x.map(isNaN) (to call isNaN on each value), I get:

true,true,true,true,false,false,false,false,false,false,false

In conclusion, isNaN looks pretty useless!

Incidentally, here are the types of those values:

x.map(function(n){return typeof n})
-> undefined,number,string,number,object,number,string,number,number,number,number
phyzome
+2  A: 

(My other comment takes a practical approach. Here's the theoretical side.)

I looked up the ECMA 262 standard, which is what Javascript implements. Their specification for isNan:

Applies ToNumber to its argument, then returns true if the result is NaN, and otherwise returns false.

Section 9.3 specifies the behavior of ToNumber (which is not a callable function, but rather a component of the type conversion system). To summarize the table, certain input types can produce a NaN. These are type undefined, type number (but only the value NaN), any object whose primitive representation is NaN, and any string that cannot be parsed. This leaves undefined, NaN, new Number(NaN), and most strings.

Any such input that produces NaN as an output when passed to ToNumber will produce a true when fed to isNaN. Since null can successfully be converted to a number, it does not produce true.

And that is why.

phyzome
A: 

Note:

"1" == 1 // true
"1" === 1 // false

The == operator does type-conversion, while === does not.

Douglas Crockford's website, a Yahoo! JavaScript evangelist, is a great resource for stuff like this.

roosteronacid
A: 

If isNaN(null) == false, then why does

testValue = null;
intValue = ((isNaN(testValue))? 0 : testValue);
alert(intValue);

tell me that 'intValue' is NaN? It seems inconsistent that null is treated like 0 by the isNaN function but not in normal arithmetic.

Dazed