I cannot tell you why, but undefined
and NaN
are actually properties of the global object:
15.1.1.1 NaN
The value of NaN is NaN (see 8.5). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
(...)
15.1.1.3 undefined
The value of undefined
is undefined (see 8.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
There is a difference between the value undefined
(NaN
) and the corresponding property.
You might notice the [[Writable]]: false
. I'm not sure whether this new in ES5 (and might not be adapted by all browsers), but in newer browsers (tested in Firefox 6), assigning a new value to undefined
has no effect:
[12:28:15.090] < undefined = "foo"
[12:28:15.093] > "foo"
[12:28:19.882] < undefined
[12:28:19.883] > undefined
So although it seems you can assign a new value, you actually cannot.
Why they are not reserved keywords?
Not sure if there was a specific reason to not make them reserved keywords, but it was decided against it. The language still works. You cannot override these values, so it's fine.
The only way to test whether a number is NaN
, is to use isNaN()
anyway.