JavaScript is like magic! One of its most magical tricks? Hoisting! 🎩✨Have you ever written code that mysteriously worked, even though you declared variables after using them? That’s called hoisting in JavaScript!
In this post, we’ll break down hoisting, explain how it relates to variable scope, and guide you from basic understanding to pro-level mastery—all while keeping it fun, simple, and engaging! Let’s get started! 🚀
Table of Contents
What Is Hoisting in JavaScript?
Let’s start from the beginning. In JavaScript, hoisting applies to variables and functions, which means variables and functions are “moved” to the top of their scope ahead of execution of the code. So you can use variables and functions even if you declare them afterward, but, of course, there is more to this.
Imagine this: You walk into a concert and the band’s instruments have already taken their place on stage before they have begun playing. JavaScript does the same thing with variables, it “sets the stage” before running your code.🎸🎤
How Does Hoisting Work?
JavaScript hoisting works with both variables and functions, but it behaves differently depending on how you declare them. To understand hoisting fully, we need to dive into var, let, and const. Let’s break it down:
Hoisting with var :
When using var to declare variables, variables declared with var are hoisted to the top of their scope but with a twist- they’re initialized with undefined. Here’s an example:
console.log(name); // Outputs: undefined var name = 'WebDevTales';
What happens here? JavaScript sees the var name declaration and hoists it to the top, but it doesn’t assign the value ‘WebDevTales’ until it reaches that line. Did it confuse you? Yeah let me break it down more.
- Hoisting: When JavaScript encounters the
var namedeclaration, it “hoists” it to the top of the scope. This means that the declaration is moved to the top of the script, but not the assignment. - Initialization with undefined: When the
var namedeclaration is hoisted, it is initialized with a value ofundefined. This is whyconsole.log(name)outputsundefined. - Assignment happens later: The assignment of the value
'WebDevTales'tonamehappens when the execution reaches the linevar name = 'WebDevTales';. This is why the value'WebDevTales'is not assigned until later.
Think of it like this:
// Hoisted declaration, initialized with undefined var name; console.log(name); // Outputs: undefined // Assignment happens here name = 'WebDevTales';
Think of it like this: The var declaration is invited to the party early but doesn’t start having fun until later. 🎉
Hoisting with let and const
Now, here’s where things get interesting. Variables declared with let and const are hoisted, BUT they are placed into a ‘temporal dead zone’ (TDZ) until the code hits that line where they are defined. This means you cannot use them before they are declared.
Did it make sense in your head? No! Then let me explain this using a code snippet.
console.log(age); // Outputs: ReferenceError: age is not defined let age; // Declaration, not initialized age = 25; // Assignment
In this example, JavaScript is aware of the age variable because it hoists the declaration, but it won’t allow you to access it until you have assigned a value. It’s like having a VIP pass but being turned away at the entrance until the club opens. 🎫🚫
Comparison of Hoisting in JavaScript (var, let, and const)

Scope in JavaScript: Where Do Variables Live?
Now that we know about hoisting, let’s talk about scope. Scope determines where variables are accessible in your code. There are a few types of scope you need to know about:
Global Scope
When you declare a variable outside any function or block, it lives in the global scope. That means it’s available everywhere in your code.
var city = "New York"; // Global scope
function getCity() {
console.log(city); // Accessing global variable
}
getCity(); // Outputs: "New York"
- The variable
cityis declared in the global scope with the value “New York”. - The
getCity()function is defined, which has access to the global scope. - Inside the
getCity()function,console.log(city)is used to log the value of thecityvariable. - The
getCity()function can access the globalcityvariable because it is in the same scope. - When the
getCity()function is called, it executes the code inside the function, which logs the value of thecityvariable to the console. - The output of the
getCity()function call is “New York”, which is the value of thecityvariable in the global scope.
Function Scope
Now, let’s look at variables declared inside a function using var. These variables have function scope meaning that you access them only inside that one specific function.
function greet() {
var name = "John";
console.log(name); // Works fine
}
console.log(name); // Error: name is not defined
To get Output: John outside the function you need to write it like this.
function greet() {
var name = "John";
console.log(name); // Works fine
}
greet(); // Outputs: JohnThink of the function scope like a private backstage pass—you can only access the VIP area inside the function. 🎟️✨
Block Scope (let and const)
let and const bring us into the world of block scope. Block-scoped variables are only accessible within the {} where they’re declared.
if (true) {
let fruit = "Apple";
console.log(fruit); // Works fine
}
console.log(fruit); // Error: fruit is not defined
In this case, the variable fruit only exists within the {} of the if statement. It’s like putting up walls around a room—nobody outside can see what’s happening inside. 🧱🔒
Comparison of Scope Types in JavaScript

Combining Hoisting and Scope: What Happens?
Let’s see how hoisting and scope work together:
function showFruit() {
console.log(fruit); // undefined (hoisted!)
var fruit = "Banana";
}
showFruit();
Even though fruit is hoisted, it’s still limited by the function scope. So, the variable exists but hasn’t been assigned a value yet.
But what happens with let or const?
function showFruit() {
console.log(fruit); // Error: Cannot access 'fruit' before initialization
let fruit = "Banana";
}
showFruit();
function showFruit() {
console.log(fruit); // Error: Cannot access 'fruit' before initialization
const fruit = "Banana";
}
showFruit();Here, you get an error because let and const doesn’t allow you to use the variable before it’s declared—it’s in the TDZ (temporal dead zone)!
Common Mistakes with Hoisting (And How to Avoid Them)
- Using
varwithout realizing it’s hoisted: If you’re not careful,varcan lead to unexpected results. Solution: Useletorconstfor safer scoping. - Accessing
letorconstvariables before initialization: This will throw an error due to the TDZ. Solution: Always declare your variables at the top of their block.
Best Practices for Hoisting and Scope in JavaScript
- Always use
letorconst: Avoid usingvarunless you have a specific reason to. - Declare variables at the top of their scope: This will avoid TDZ errors and make your code easier to read.
- Use
constfor constants: If a value doesn’t need to change, useconstfor clarity and safety.
Pro Tips for Mastering Hoisting
- Understand Function Hoisting: In JavaScript, function declarations are hoisted, but function expressions are not. This means you can call a function before it’s declared if it’s a function declaration.
sayHello(); // Works because it's hoisted
function sayHello() {
console.log("Hello!");
}
- Function Expressions Are Not Hoisted: If you declare a function using an expression, it will not be hoisted.
sayHello(); // Error: sayHello is not a function
const sayHello = function() {
console.log("Hello!");
};
Variable Behavior in Different Scopes

Conclusion: Understanding Hoisting and Scope Is Key to Writing Better Code!
And there you have it! 🎉
By this time, you should feel pretty comfortable with hoisting and scope in JavaScript. Both are quite crucial to creating clean code that is also efficient and doesn’t have bugs hidden within it. Working through small projects or large-scale applications, mastery of both will propel you from beginner to pro!
So, go ahead—experiment with your code, understand the magic behind the scenes, and keep growing as a developer. 💻✨
Also Read:
- Read more about JavaScript hoisting.
FAQs
1. What is hoisting in JavaScript?
Hoisting is the JavaScript mechanism where variable and function declarations are moved to the top of their scope before code execution.
2. Can I use let or const before declaring them?
No, let and const are hoisted but remain in the temporal dead zone until they are initialized.
3. Does hoisting apply to functions in JavaScript?
Yes, but only to function declarations. Function expressions are not hoisted.
4. What is the best way to avoid hoisting issues?
Use let and const to declare variables, and always declare them at the top of their scope.
5. Why should I avoid using var?var can lead to unexpected behavior due to its hoisting and function-scoped nature. let and const offer safer, more predictable scoping.



