Free email newsletter: “ES.next News

2015-10-19

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

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 a variable 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 a variable 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 existence, but aren’t. Therefore, being warned seems desirable.

Furthermore, this kind of check is only useful for conditionally creating global variables. That’s something that only advanced JavaScript programmers should do and that can only be achieved via var. Additionally, there is hope that ES6 modules will eventually obviate the need for conditionally creating global variables.

There is a way to check whether a variable exists that does not involve typeof:

    // 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 ES6 modules).

Futher reading

Sources of this blog post:

No comments: