JavaScript Hoisting: var, let, and const Explained
Variable hoisting in JavaScript is a mechanism where variable and
function declarations are moved to the top of their containing scope
during the compilation phase before code execution. While all variable
declarations (var, let, and
const) are hoisted, they behave differently regarding
initialization and accessibility. This guide explains how hoisting works
in JavaScript and breaks down the specific behaviors and rules governing
var, let, and const.
What is Hoisting?
During the creation phase of the JavaScript execution context, the JavaScript engine scans the code for variable and function declarations and allocates memory for them before executing any code line by line. As a result, variables can be referenced in code before the lines where they are explicitly declared, though the outcome depends on the keyword used to declare them.
Hoisting with var
Variables declared with var are hoisted and
automatically initialized with the default value of
undefined.
- Scope: Function-scoped or globally scoped.
- Initialization: Initialized to
undefinedduring the hoisting phase. - Behavior: If a
varvariable is accessed before its declaration line, it returnsundefinedinstead of throwing a reference error.
console.log(greeting); // Output: undefined
var greeting = "Hello, World!";
console.log(greeting); // Output: "Hello, World!"Under the hood, the engine interprets the code as:
var greeting; // Hoisted and initialized to undefined
console.log(greeting); // undefined
greeting = "Hello, World!";
console.log(greeting); // "Hello, World!"Hoisting with let and
const
Variables declared with let and const are
also hoisted to the top of their block scope, but unlike
var, they are not initialized.
- Scope: Block-scoped (enclosed within
{}). - Initialization: Not initialized during hoisting; initialized only when the execution reaches the declaration line.
- Behavior: Accessing a
letorconstvariable before its declaration causes aReferenceError.
console.log(count); // Throws ReferenceError: Cannot access 'count' before initialization
let count = 10;
console.log(PI); // Throws ReferenceError: Cannot access 'PI' before initialization
const PI = 3.14159;The Temporal Dead Zone (TDZ)
The period between entering the scope where a let or
const variable is declared and the actual line where it is
initialized is called the Temporal Dead Zone (TDZ). Any
attempt to read or write to the variable while it is in the TDZ will
result in a runtime ReferenceError.
{
// TDZ for 'name' starts here
// console.log(name); // Throws ReferenceError
let name = "Alice"; // TDZ ends here
console.log(name); // Output: "Alice"
}Key Differences
| Feature | var |
let |
const |
|---|---|---|---|
| Hoisted | Yes | Yes | Yes |
| Initialized on Hoist | Yes (undefined) |
No | No |
| Subject to TDZ | No | Yes | Yes |
| Scope | Function / Global | Block | Block |
| Reassignable | Yes | Yes | No |