Christoph Schiessl's Blog

On JavaScript’s undefined

All syntax highlighters I’ve ever worked with, treat JavaScript’s undefined as a keyword. However, that’s a misconception.

1
2
3
// global scope
undefined = 123;   // assign to `undefined`
undefined === 123; // ==> evaluates to true

The code snippet above certainly looks strange, but it’s actually valid JavaScript. Rouge, the highlighter I’m using for this blog, is misleading, because it considers undefined to be 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 a lot of changes, but one is of particular importance for us: 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. writeable undefined).
  • false if you are using a recent browser. For instance, Google Chrome implements the new behavior (i.e. non-writeable undefined).

The non-writeable undefined in ES5 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. Observe:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(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 saying the following: It’s your responsibility as a JavaScript developer to ensure that undefined really refers to the value its name suggests (i.e. typeof undefined === 'undefined').

comments powered by Disqus