JavaScript Temporal Dead Zone
The Temporal Dead Zone is a behavior in JavaScript that occurs when declaring a variable with the let
and const
keywords, but not with var
. A shorthand you’ll often hear to describe it is that “Let’s don’t hoist,” but this is not technically true. Read on for a brief description of what’s really occurring.
In JavaScript, variable declarations (but not assignments) are hoisted to the top of the scope. The code below works as expected:
function myFunc(){
var greeting = "Hello World!";
console.log(greeting);
}
myFunc(); // "Hello World!"
But if you reverse the order and try to run console.log
on a variable before creating it?
function myFunc(){
console.log(greeting);
var greeting = "Hello World!";
}
Which of these three options will be the output?
- ‘Hello World!’
- An error saying
greeting
is not yet defined Undefined
The answer is undefined
because the variable declaration is hoisted to the top of the scope. So in the eyes of the JavaScript interpreter, the code really looks as follows:
function myFunc(){
var greeting;
console.log(greeting);
greeting = 'Hello World!'
}
The JavaScript interpreter works in a two-step process:
- compile time: run through all code looking for variable/function declarations
- runtime: execute the code including assignments and function invocations
Therefore on the first line, greeting
is defined but has no assignment. JavaScript automatically provides the value undefined
to defined variables without any variable. On line 2 the result will be undefined
because the assignment does not occur until line three.
But if you use either the let
or const
keywords to declare a variable, this same code will throw an error:
function myFunc() {
console.log(greeting);
let greeting = 'Hello World!';
}
myFunc(); // ReferenceError: greeting is not defined
function myFunc() {
console.log(greeting);
const greeting = 'Hello World!';
}
myFunc(); // ReferenceError: greeting is not defined
This is the Temporal Dead Zone where we’re trying to access a variable that has not yet been initialized (it has been declared and therefore exists, but has no value, not even undefined
). It’s common to hear the phrase, “let/const don’t hoist” as a shorthand to remember this behavior. But technically something else is going on.
When we use the var
keyword, two things actually happen:
- at compile time, the variable is added to the enclosing lexical scope
- at runtime, when the scope is entered any variables added to the lexical environment are initialized to the
undefined
value so they are available to use in the scope
The let
and const
keywords do step 1–so technically they do hoist–but not step 2, the assignment to undefined
. Therefore it’s more accurate to say that let/const
do hoist but don’t get initialized.
The end result is the same. Just remember that when using let/const
you should always move variable declarations to the top of your scope to avoid the temporal dead zone.
Want to improve your JavaScript? I have a list of recommended JavaScript books.