Hoisting
Hoisting in JavaScript
Demystifying the creation phase behavior of var, let, const, and function declarations.
The Morning Classroom Roll Call
Hoisting does not physically move your code lines to the top of the file. It is the result of the engine setting up memory allocations during the Execution Context Creation Phase before executing any code.
Creation Phase Memory Allocation
The engine parses the entire script, noting all variable and function identifiers before running line 1.
Function Declarations Hoisting
Traditional `function greet() {}` declarations are hoisted completely into memory along with their entire function body. You can safely call them before their declaration line.
Var Hoisting with Undefined
Variables declared with `var` are allocated and immediately initialized with the primitive value `undefined`.
Let and Const: The Temporal Dead Zone (TDZ)
Variables declared with `let` and `const` are also hoisted (the engine knows about them), but they remain UNINITIALIZED. Any access before their declaration line triggers a `ReferenceError`.
Function Expressions vs Declarations
When assigning a function to a variable (`const myFn = function() {}`), only the variable name is hoisted according to variable rules. Calling it early throws a TypeError or ReferenceError.
Comparing Function Declarations, var, and the let/const TDZ:
// 1. Function Declarations work anywhere in scope
sayHello(); // Output: "Hello from hoisted function!"
function sayHello() {
console.log("Hello from hoisted function!");
}
// 2. var is hoisted as undefined
console.log(nickname); // Output: undefined
var nickname = "Flash";
// 3. let/const in TDZ
try {
console.log(realName);
} catch (err) {
console.log(err.name + ": " + err.message);
}
let realName = "Barry Allen";
Hello from hoisted function!
undefined
ReferenceError: Cannot access 'realName' before initialization
Calling Function Expressions Before Assignment
The Risk: Using `var fn = () => {}` and calling `fn()` before assignment throws `TypeError: fn is not a function` because `fn` is currently `undefined`.
The Fix: Declare functions using `function name() {}` if you need hoisting, or declare arrow functions at the top of your modules before calling them.
- ✓ Hoisting is an artifact of the Execution Context Creation Phase.
- ✓ Function Declarations: Fully hoisted with code body.
- ✓ `var`: Hoisted and initialized to `undefined`.
- ✓ `let` and `const`: Hoisted but uninitialized; protected by Temporal Dead Zone (TDZ).
- ✓ Function expressions and arrow functions are governed by variable hoisting rules.