This post looks at two special values that can be the result of operations that normally return numbers: NaN and Infinity.
> Number("xyz")
NaN
NaN has some Koan-like qualities. Its name is “not a number”, but it’s also not not a number (triggered by a tweet by Ariya Hidayat):
> NaN !== NaN
true
Yet, its type is “number”.
> typeof NaN
'number'
> isNaN(NaN)
true
Kit Cambridge (via Mathias Bynens) points out a pitfall of isNaN(): It coerces its argument to number and will thus even return true for strings that cannot be converted to numbers:
> Number("xyz")
NaN
> isNaN("xyz")
true
For the same reason, isNaN will also return true for many objects:
> Number({})
NaN
> isNaN({})
true
> Number(["xzy"])
NaN
> isNaN(["xzy"])
true
Consult [1] for details on the conversion algorithm. It is possible to override valueOf to control the result of the conversion to number:
> var obj = { valueOf: function () { return NaN } };
> Number(obj)
NaN
> isNaN(obj)
true
Cambridge’s suggested work-around is to exploit the fact that NaN is the only value x that is non-reflexive (x !== x):
function myIsNaN(x) {
return x !== x;
}
A fixed version of isNaN will probably be added to ECMAScript 6 as Number.isNaN(). Crockford’s specification of that function better reveals what one is trying to do than Cambridge’s version. It looks as follows (simplified for explanatory purposes):
Number.isNaN = function (value) {
return typeof value === 'number' && isNaN(value);
};
> 3/0
Infinity
You can’t play positive and negative infinity against each other:
> Infinity - Infinity
NaN
It also turns out that “beyond infinity” is still infinity:
> Infinity + Infinity
Infinity
> 5 * Infinity
Infinity