Hoisting in JavaScript: Understanding var, let, and const

Pranav BagalPranav Bagal
3 min read

I used to believe that hoisting in JavaScript only applied to variables declared with the var keyword. However, I recently discovered that variables declared with let and const are also hoisted, though they behave differently. In this article, I’ll explain what hoisting is, how it works with var, let, and const, and why these differences matter for writing reliable code.

What is Hoisting?

Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their containing scope during the compilation phase, before the code executes. However, only the declarations are hoisted — not the initializations or assignments. This behavior affects how and when variables can be accessed in your code.

Hoisting with var

Variables declared with var are hoisted to the top of their scope—either the global scope or the function scope. During the creation phase of the execution context, these variables are allocated memory and automatically initialized to undefined. This explains why you can access a var variable before its declaration without triggering an error, though its value will be undefined until assigned.

Example:

console.log(x); // Output: undefined
var x = 10;
console.log(x); // Output: 10

What’s Happening?

  1. The JavaScript engine creates the Global Execution Context (GEC).

  2. In the creation phase, the declaration var x is hoisted, and x is initialized to undefined.

  3. When console.log(x) runs, x exists but has the value undefined.

  4. Later, x = 10 assigns the value, so the second console.log(x) outputs 10.

Key Point: Variables declared with var are hoisted and initialized to undefined, making them accessible (though undefined) before their declaration.

Hoisting with let and const

Variables declared with let and const are also hoisted, but unlike var, they are not initialized until the code reaches their declaration. This uninitialized period—from the start of their block scope to their declaration—is called the Temporal Dead Zone (TDZ). Attempting to access these variables before their declaration results in a ReferenceError.

Example:

console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 20;
console.log(y); // Output: 20

What’s Happening?

  1. The declaration let y is hoisted to the top of its scope.

  2. However, y remains in the Temporal Dead Zone until the line let y = 20 executes.

  3. Accessing y before this line throws a ReferenceError because it’s hoisted but not initialized.

Another Example:

console.log(x); // ReferenceError: x is not defined
let y = 10;
  • Here, x is undeclared, so JavaScript throws ReferenceError: x is not defined.

  • In contrast, accessing y before its declaration results in ReferenceError: Cannot access 'y' before initialization, showing that y is hoisted but inaccessible due to the TDZ.

Key Point: Variables declared with let and const are hoisted but remain in the Temporal Dead Zone until their declaration, preventing access before initialization.

Conclusion

  • All variables — whether declared with var, let, or const—are hoisted in JavaScript, meaning their declarations are moved to the top of their scope.

  • var variables are initialized with undefined, allowing access before declaration (though with an undefined value).

  • let and const variables are hoisted but remain in the Temporal Dead Zone until their declaration, causing a ReferenceError if accessed early.

Understanding hoisting and its differences across var, let, and const is crucial for avoiding unexpected errors and writing cleaner, more predictable JavaScript code.

Acknowledgments: Thanks to WebDev Cohort 1 by ChaiCode for deepening my understanding of this topic.

#chaiaurcode #chaicode

0
Subscribe to my newsletter

Read articles from Pranav Bagal directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pranav Bagal
Pranav Bagal