Why JavaScript’s undefined
Isn’t What You Think It Is
by Christoph Schiessl on JavaScript
All syntax highlighters I've ever worked with treat JavaScript's undefined
as a keyword. However, that's a misconception.
// global scope
undefined = 123; // assign to `undefined`
undefined === 123; // ==> evaluates to true
The code snippet above looks strange, but it's valid JavaScript. Pygments, the highlighter I'm using for this website, is misleading because it considers undefined
a keyword. But in reality, there's nothing special about undefined
:
- Syntactically, it's an ordinary identifier (not a keyword).
- Semantically, it's a property of the so-called Global Object.
I'm assuming you are using a more or less recent browser to read this article. If so, you, unfortunately, can't reproduce the above behavior because your browser implements the ECMAScript 5 (short: ES5) standard. ES5 introduces many changes, but one is particularly important in this context — namely, they updated the undefined
property to be non-writeable.
In a nutshell, this means that the last line of the above snippet evaluates to...
- ...
true
if you are using an old browser. For instance, Internet Explorer 8 implements the old behavior (i.e., writeableundefined
). - ...
false
if you are using a recent browser. For instance, Google Chrome implements the new behavior (i.e., non-writeableundefined
).
The non-writeable undefined
in ES5 (or newer) mitigates the problem, but it's still easy to construct a situation where undefined
is not what you expect. All it takes is a function scope and a var
...
(function () {
// Remember: `undefined` is an identifier (not a keyword)
var undefined = 'foobar';
// Clearly, 'foobar' is defined (its type is 'string')
if ('foobar' === undefined) {
console.log('foobar is *UN*defined!!!');
} else {
console.log('foobar is defined!!!');
}
})();
// Output: foobar is *UN*defined!!!
Let me conclude by pointing out that it is your responsibility as a JavaScript developer to ensure that undefined
really refers to the value its name suggests. You are responsible for ensuring that typeof undefined === 'undefined'
is always true.
Thank you for reading, and see you soon!