Why is there a “temporal dead zone” in ES6?

By Axel Rauschmayer

In ECMAScript 6, accessing a let or const variable before its declaration (within its scope) causes a ReferenceError. The time span when that happens, between the creation of a variable’s binding and its declaration is called the temporal dead zone.

For more information, consult Sect. “The temporal dead zone” in “Exploring ES6”. Here, I’d like to answer two questions:

  • Why is there a temporal dead zone?
  • Why does typeof cause a ReferenceError for variables in the TDZ?

Why is there a temporal dead zone?

  • To catch programming errors: Being able to access a variable before its declaration is strange. If you do so, it is normally by accident and you should be warned about it.
  • For const: Making const work properly is difficult. Quoting Allen Wirfs-Brock: “TDZs … provide a rational semantics for const. There was significant technical discussion of that topic and TDZs emerged as the best solution.” let also has a temporal dead zone so that switching between let and const doesn’t change behavior in unexpected ways.
  • Future-proofing for guards: JavaScript may eventually have guards, a mechanism for enforcing at runtime that a variable has the correct value (think runtime type check). If the value of a variable is undefined before its declaration then that value may be in conflict with the guarantee given by its guard.

Why does typeof cause a ReferenceError for variables in the TDZ?

If you access a variable in the temporal dead zone via typeof, you get an error, too:

        console.log(typeof foo); // ReferenceError
        console.log(typeof someVariableThatDoesntExist); // 'undefined'
        let foo;

The rationale here is as follows: foo is not undeclared, it is uninitialized. You should be aware of its existencee, but aren’t. Therefore, being warned seems desirable.

Furthermore, this kind of check is only useful for conditionally creating global variables. That can only be done via var (not by let or const) and there are different ways of performing the check:

    // With `typeof`
    if (typeof someGlobal === 'undefined') {
        var someGlobal = { ··· };
    // Without `typeof`
    if (!('someGlobal' in window)) {
        window.someGlobal = { ··· };

The former way of creating a global variable only works in global scope (and therefore not inside an ES6 module).

Futher reading

Sources of this blog post:

Source:: 2ality