Hoisting & Temporal Dead Zone
When learning JavaScript, two of the most confusing concepts are hoisting and the Temporal Dead Zone (TDZ). In this article, we’ll break them down with simple explanations and code examples.
What is Hoisting?
Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their scope before code execution.
Important: only declarations are hoisted, not assignments.
Example with functions
greet();
function greet() {
console.log("Hello from hoisting!");
}
✅ This works because function declarations are fully hoisted to the top of the scope.
Example with var
variables
console.log(name); // undefined
var name = "Elias";
➡️ What happened here? Internally, the engine treats it like this:
var name; // hoisted
console.log(name); // undefined
name = "Elias";
That’s why it doesn’t throw an error but logs undefined
.
let
and const
change the rules
With ES6, let
and const
introduced the Temporal Dead Zone (TDZ).
console.log(lastName); // ❌ ReferenceError
let lastName = "Delgado";
Unlike var
, accessing the variable before its declaration throws an error.
The Temporal Dead Zone (TDZ)
The TDZ is the period between the start of a scope and the point where a variable declared with let
or const
is initialized.
During this time, the variable exists but cannot be accessed.
{
// 'x' exists in this block
// but is in the TDZ until initialized
console.log(x); // ❌ ReferenceError
let x = 10;
console.log(x); // ✅ 10
}
Example with const
const
behaves the same as let
regarding the TDZ but also requires immediate initialization:
console.log(pi); // ❌ ReferenceError
const pi = 3.1416;
Why does the TDZ exist?
The TDZ was introduced to avoid logical errors and make code more predictable.
Consider this with var
:
function example() {
console.log(message); // undefined
if (false) {
var message = "Hello!";
}
}
👉 This can lead to hard-to-find bugs.
With let
or const
, the engine won’t let you access the variable too early:
function example() {
console.log(message); // ❌ ReferenceError
if (false) {
let message = "Hello!";
}
}
✅ Much safer.
Quick recap
- Function declarations: fully hoisted (can be used before definition).
var
variables: hoisted asundefined
.let
andconst
variables: exist in the TDZ until initialized.- TDZ prevents silent bugs and makes code more reliable.
Conclusion
Hoisting is one of those JavaScript quirks that often confuse beginners, but once you understand how it works along with the Temporal Dead Zone, your code becomes more predictable and safe.
👉 Practical rule of thumb:
- Always use
let
andconst
(preferconst
by default). - Avoid
var
to prevent unexpected behavior.