Don’t Assume undefined is undefined

Sarah has a bug where she knows that:

typeof(foo) == 'undefined'

is `true`, but when she tested:

foo == undefined

it is `false`. How can this be?

This is because `undefined` is not a literal in ECMAscript. Lots of people use `undefined` expecting it to be __undefined__, but it doesn't _have_ to be, at least not according to the spec. (`null` on the other hand, is a literal, defined to be the sole member of the `Null` type, just as the literals `true` and `false` are the only members of the `Boolean` type and cannot be redefined, and `1`, `2`, ... `Infinity` are `Number` literals.)

If you try this in the debugger:

global[undefined] = 42

you will get a warning from the compiler, but now when you type:

undefined

you will find that it is indeed 42!

What's the _right_ way to test for __undefined__? It depends. Do you _really_ need to know if a variable is __undefined__? If so, the typeof test is one valid way. The other valid way would be:

foo === void 0

`void` will cast any value to __undefined__ -- 0 is just a convenient (literal) value to use. Note the use of `===` to test for identical to __undefined__, if you really are testing for __undefined__, because:

null == void 0

is also true, so if you used `==` you would only know that foo was either `null` or __undefined__.

If all you need to know is that foo is not __undefined__, `null`, `false`, `0`, or `""` (an empty string), then you can use:

Boolean(foo)

or:

!!foo

or:

if (foo) { ... }

because all of __undefined__, `null`, `false`, `0` and `""` coerce to `false` in a boolean context.

The moral of the story is:
Don't assume `undefined` is __undefined__.
If you really need the __undefined__ value, use `void 0`, or test for `typeof(...) == 'undefined'`.

Comments are closed.