Hoisting
TL;DR
Hoisting is JavaScript’s behavior of putting variable and function declarations into memory during the “Creation Phase” before actually executing the code. This makes it appear as if declarations are magically moved to the top of the file, allowing you to call a function before you write it.
Mental Model
How It Works
Hoisting behaves differently depending on how you declare things:
functionDeclarations: Fully hoisted. The entire function body is put into memory. You can call it anywhere.varDeclarations: Partially hoisted. The variable name is put into memory, but it is initialized with the valueundefined. The actual assignment (= 10) happens during the execution phase.letandconstDeclarations: Technically hoisted (the engine knows they exist), but they are placed in the Temporal Dead Zone (TDZ). You cannot access them before their actual line of code, resulting in aReferenceError.- Function Expressions (
var a = function() {}): Behave like standard variables. Thevarname is hoisted asundefined, but the function itself is not available until the line executes.
Example
// 1. Function Declaration (Fully Hoisted)
sayHello(); // Output: "Hello!"
function sayHello() {
console.log("Hello!");
}
// 2. var (Hoisted as undefined)
console.log(age); // Output: undefined
var age = 25;
// 3. let/const (Hoisted, but in TDZ)
// console.log(name); // ReferenceError!
let name = "Alice";
// 4. Function Expression (var rules apply)
// bark(); // TypeError: bark is not a function (it's undefined!)
var bark = function() {
console.log("Woof");
}
Common Output Question
var myVar = "Global";
function scopeTest() {
console.log(myVar);
var myVar = "Local";
}
scopeTest();
Q: What does this output and why?
A: undefined.
When scopeTest runs, it creates a new Execution Context. Inside that context, the local var myVar is hoisted to the top of the function and initialized as undefined. When console.log(myVar) runs, it finds the local hoisted variable (undefined), overriding the global variable.
Senior Interview Question
Q: If let and const are hoisted, why do they throw an error instead of returning undefined like var?
A: TC39 (the JavaScript committee) intentionally designed let and const to remain uninitialized in the Temporal Dead Zone to catch bugs. var returning undefined silently caused millions of hard-to-track bugs where developers accidentally used variables before giving them values. By throwing a hard ReferenceError, modern JavaScript forces developers to write safer top-down code, catching logical initialization errors immediately at runtime.