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:
typeof
cause a ReferenceError
for a variable in the TDZ?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.undefined
before its declaration then that value may be in conflict with the guarantee given by its guard.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 aVariableThatDoesntExist); // '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).
Sources of this blog post: