JavaScript Hoisting and the Temporal Dead Zone Explained
If someone asked you to explain JavaScript Hoisting, would you say: “JavaScript moves variables to the top”
JavaScript Hoisting and the Temporal Dead Zone Explained
If someone asked you to explain JavaScript Hoisting, would you say: “JavaScript moves variables to the top”
That’s the explanation many of us learned or found online.
It’s also misleading.
Nothing is actually moved. Instead, the JavaScript Engine prepares the code before execution which causes var, let, and const to behave differently. Once you understand the process, concepts like these become easy to reason about.
To understand what’s happening behind the scenes, let’s look at the following example:
console.log(a); // undefined
sayHi(); // Hello
console.log(b); // ReferenceError
var a = 10;
function sayHi(){
console.log("Hello");
}
let b = 20;
Before execution of the code, JavaScript creates an execution context (the environment in which the code will run).
When the script starts, JavaScript Engine creates a Global Execution Context. Later, whenever a function is invoked, a new Function Execution Context is created.
An execution context provides everything the engine needs to execute the code, such as variable bindings, function declarations, and the value of this.
Behind the scenes, an execution context also includes concepts like Lexical Environment. But that’s a topic worthy of its own article. For now, focus on the parts that help us understand hoisting and the TDZ.
Every execution context goes through these two phases:
- Creation Phase (Memory Creation Phase): The engine allocates memory for variables and function declarations before executing any code.
- Execution Phase: The engine executes the code line by line, assigns values to variables, and invokes functions.
These phases are the key to understanding hoisting and the TDZ.
So, let’s understand these phases with the help of example provided above. For this script, the execution context first enters the Creation Phase and in this phase, memory is allocated for variables and functions. You can think of it like this:

fig 1 : Memory Allocation
During Creation Phase, variables declared with ‘var’ are initialized with the value ‘undefined’, whereas variables declared with ‘let’ or ‘const’ are created but remain uninitialized until execution reaches their declaration.
This difference in initialization is exactly why accessing a ‘var’ variable before its declaration returns ‘undefined’ , while accessing the ‘let’ or ‘const’ variable throws a ‘ReferenceError’.
Function declarations are fully initialized during this phase.
Now, during Execution Phase, the engine goes line by line.
console.log(a);
For this line of code, the engine looks up the binding for “a” in the execution context environment and gets the value “undefined”, which is then printed.
sayHi();
Now, the engine resolves the function binding and invokes the function.(Keep in mind that for this function, a Function Execution Context will also be created).
console.log(b);
Now, we encounter the key difference between ‘var’ and ‘let’. As the engine looks up the binding for “b” , since ‘b’ has not been initialized yet, accessing it results in a ReferenceError. This period is known as the Temporal Dead Zone.
- Temporal Dead Zone (TDZ) : It refers to the phase in the execution context where ‘let’ and ‘const’ variables exist in the memory but can’t be accessed before initialization.
- Hoisting : It is a JavaScript behaviour where declarations are processed during the creation phase of an execution context, making variables and functions available according to their declaration type.
var a = 10;
Now, while executing this line of code, the assignment ‘ = 10 ’ updates the existing binding of ‘a’ from ‘undefined’ to ‘10’. Later, when the execution reaches ‘ let b = 20; ’ , the binding for ‘b’ is initialized with the value ‘20’. If ‘ console.log(b); ’ were placed after ‘ let b = 20; ’ it would print ‘20’ instead of throwing a ‘ReferenceError’.
That’s all.
Once you understand the lifecycle of an execution context, hoisting becomes easy.
I hope this article helped clarify one of JavaScript’s most misunderstood concepts.
메타데이터
- post_id
- d60bfa47a6de
- slug
- javascript-hoisting-and-the-temporal-dead-zone-explained-d60bfa47a6de
- url
- https://medium.com/@Resolve.dev/javascript-hoisting-and-the-temporal-dead-zone-explained-d60bfa47a6de
- canonical_url
- https://medium.com/@Resolve.dev/javascript-hoisting-and-the-temporal-dead-zone-explained-d60bfa47a6de
- author_url
- https://medium.com/@Resolve.dev
- status
- ok
- fetched_at
- 2026-08-22 11:42:19