In Javascript:
NaN === NaN; // false
I was trying to determine when isNaN(foo)
is not just equivalent to +foo
"is" NaN
. But I don't know how to tell if something is NaN
except by using isNaN
, which says yes for many things, none of which ===
NaN.
So I think the right way to do this would be to work around other possibilities:
typeof NaN === 'number' // true
Therefore I think
typeof(foo) === 'number' && isNaN(foo)
Is the closest to what I am thinking of. It makes sense since it makes sense that NaN
would be the only number that isn't a number, or something. Is this correct, and is this the best way?
Use that to your advantage:
foo !== foo
This is equivalent to typeof foo === 'number' && isNaN(foo)
, and is what Underscore.js uses to check for exactly NaN
, too.
The reason that NaN isn't equal to itself is that two calculations can become NaN for different reasons. If you do two calculations and compare the results, you don't want them to be equal if one of the values are NaN, or both of them.
The isNaN
method works fine as long as you only use it on numerical values. It gives unintuitive results for a lot of other types, so you simply shouldn't use it on anything other than numbers.
If you can use ECMAScript 6, you have Object.is
:
return Object.is(foo, NaN);
Object.is()
determines whether two values are the same value. Two values are the same if one of the following holds:
[...]
MDN also suggests a Polyfill if Object.is
isn't defined (uses the same foo!==foo
trick):
if (!Object.is) {
Object.is = function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
}