Hoisting is JavaScript's behavior of moving declarations to the top of their scope during the compilation phase, before the code is executed. This means you can sometimes use variables or functions before they appear (are declared) in your code.
How Hoisting Works
When JavaScript code runs, it goes through two phases:
- Compilation phase - Declarations are processed and memory is allocated
- Execution phase - Code runs line by line
During compilation, JavaScript "hoists" (moves) declarations to the top of their scope.
Function Hoisting
Functions declared with the function keyword are fully hoisted - both the declaration AND the definition.
// This works!
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
What JavaScript actually does behind the scenes:
// JavaScript hoists the entire function to the top
function sayHello() {
console.log("Hello!");
}
sayHello(); // "Hello!"
Function Expressions Are NOT Fully Hoisted ❌
// This throws an error!
greet(); // TypeError: greet is not a function
var greet = function() {
console.log("Hi!");
};
var Hoisting
Variables declared with var are hoisted, but only the declaration is hoisted, not the initialization.
console.log(x); // undefined (not an error!)
var x = 5;
console.log(x); // 5
What JavaScript sees:
var x; // Declaration hoisted to top
console.log(x); // undefined
x = 5; // Initialization stays in place
console.log(x); // 5
let and const Hoisting (The Temporal Dead Zone)
let and const are also hoisted, but they're not initialized. This creates the "Temporal Dead Zone" (TDZ) - the period between entering scope and the actual declaration.
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
console.log(z); // ReferenceError: Cannot access 'z' before initialization
const z = 20;
The Temporal Dead Zone:
{
// TDZ starts here for 'name'
// Any access to 'name' here throws an error
console.log(name); // ReferenceError
let name = "Alice"; // TDZ ends here
console.log(name); // "Alice" - now it works
}
Common Hoisting Examples
Example 1: Variable Confusion
var name = "Global";
function printName() {
console.log(name); // undefined (not "Global"!)
var name = "Local";
console.log(name); // "Local"
}
printName();
Why? JavaScript hoists the local var name declaration:
function printName() {
var name; // Hoisted!
console.log(name); // undefined
name = "Local";
console.log(name); // "Local"
}
Example 2: Loop Variables
console.log(i); // undefined
for (var i = 0; i < 3; i++) {
// ...
}
console.log(i); // 3 (still accessible!)
What happens:
var i; // Hoisted to top
console.log(i); // undefined
for (i = 0; i < 3; i++) {
// ...
}
console.log(i); // 3
Example 3: Function Hoisting Order
foo(); // "Second"
function foo() {
console.log("First");
}
function foo() {
console.log("Second");
}
Both functions are hoisted, but the second one overwrites the first.
Visual Comparison
// ❌ var - Hoisted but initialized as undefined
console.log(a); // undefined
var a = 1;
// ❌ let - Hoisted but NOT initialized (TDZ)
console.log(b); // ReferenceError
let b = 2;
// ❌ const - Hoisted but NOT initialized (TDZ)
console.log(c); // ReferenceError
const c = 3;
// ✅ function - Fully hoisted
myFunc(); // Works!
function myFunc() {
console.log("Hello");
}
Why Hoisting Exists
Hoisting allows for more flexible code organization, particularly with functions:
// You can organize your code with the main logic first
main();
helper1();
helper2();
// And define functions below
function main() {
console.log("Main function");
}
function helper1() {
console.log("Helper 1");
}
function helper2() {
console.log("Helper 2");
}
Best Practices to Avoid Hoisting Issues
- Always declare variables at the top of their scope
function example() {
let x, y, z; // Declare at top
// ... rest of code
}
- Use
letandconstinstead ofvar- They're safer and more predictable - Declare functions before calling them - Even though hoisting allows it, explicit order is clearer
- Enable strict mode - Helps catch hoisting-related errors
'use strict';
Key Takeaways
→ Function declarations are fully hoisted (declaration + definition)
→ var declarations are hoisted and initialized as undefined
→ let and const are hoisted but NOT initialized (Temporal Dead Zone)
→ Only declarations are hoisted, not initializations
→ Hoisting happens at the scope level (function or block scope)
Understanding hoisting helps you avoid confusing bugs and write more predictable JavaScript code!
🔍. Similar posts
Mastering Vue 3 Template Syntax: A Complete Guide
09 Feb 2026
What is ECMAScript
08 Feb 2026
JavaScript Variable : var, let, and const
08 Feb 2026