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 aReferenceError
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
: Makingconst
work properly is difficult. Quoting Allen Wirfs-Brock: “TDZs ... provide a rational semantics forconst
. 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 betweenlet
andconst
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:
Comments
Post a Comment