Glossary

Hoisting

Hoisting is JavaScript's behavior of moving function and variable declarations to the top of their scope before code runs. Function declarations are fully hoisted (callable before definition); var declarations are hoisted but not initialized (return undefined before assignment); let/const are hoisted but not accessible (Temporal Dead Zone).

Explanation

Hoisting is a two-phase process: first, JavaScript scans the scope for all declarations and "hoists" them to the top before any code executes. Second, code runs line-by-line. This is why function declarations can be called before they appear in the file — the entire function (name + body) is available from the start of the scope. var declarations are hoisted with undefined as the initial value. So: console.log(x); var x = 5; prints undefined, not a ReferenceError. The declaration (var x) is hoisted; the assignment (x = 5) is not. This is a common source of confusing bugs — the variable exists, it just doesn't have its value yet. let and const are technically hoisted too (JavaScript knows they exist from the start of the block), but they're placed in the Temporal Dead Zone (TDZ): accessing them before their declaration line throws a ReferenceError. This is more helpful behavior than var's undefined — you get an explicit error instead of silently using undefined. Function declarations (function foo() {}) are fully hoisted — you can call foo() before it appears in code. Function expressions (const foo = function() {}) and arrow functions (const foo = () => {}) are not — they're variables assigned functions, so only the variable declaration is hoisted (as undefined), not the function value.

Code Example

javascript
// Hoisting behavior demystified

// Function declarations: fully hoisted
greet('Alice'); // works! 'Hello, Alice'
function greet(name) { return `Hello, ${name}`; }

// var: declaration hoisted, assignment not
console.log(x); // undefined (not ReferenceError)
var x = 10;
console.log(x); // 10

// let/const: Temporal Dead Zone
// console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 20;
console.log(y); // 20

// Function expressions: NOT hoisted (the variable is, as undefined)
// sayHi(); // TypeError: sayHi is not a function
const sayHi = function() { return 'Hi!'; };

// Class declarations: like let — hoisted to TDZ, not callable before definition
// const dog = new Dog(); // ReferenceError
class Dog { bark() { return 'woof'; } }

// Practical rule: declare variables before using them.
// Use const/let (not var) to get helpful errors instead of silent undefined.
// Use function declarations for utility functions (hoisting is intentional here)

Why It Matters for Engineers

Hoisting explains a class of JavaScript bugs that confuse developers who don't know the mechanism: calling a function expression before defining it (TypeError), reading a var variable early (silently undefined instead of the expected value), and Temporal Dead Zone errors with let/const. Knowing hoisting rules lets you read any JavaScript file and predict exactly what's accessible at each line. Understanding hoisting also explains why many style guides recommend declaring variables at the top of their scope (make the hoisting behavior explicit) and why function declarations and expressions behave differently in the same codebase.

Related Terms

Scope · Variable · Closure · Function

Learn This In Practice

Go deeper with the full module on Beyond Vibe Code.

Programming Foundations → →