Understanding Scope, Hoisting, and Closures like a Pro!
Source: Dev.to

What is Scope?
Scope defines the accessibility of variables in your code.
Scope decides where in your code a variable can be used.
In JavaScript, every variable has a “boundary.” Outside this boundary, the variable is unavailable.
Why is Scope important?
- Prevent variable conflicts
- Manage memory efficiently
- Make code predictable
Main types of Scope
- Global Scope – accessible from anywhere
- Function Scope – accessible only within a function
- Block Scope – accessible within
{}(usingletorconst) - Lexical Scope – determined by the code’s written structure
Scope Example
let person = [1,2,3,4,5]; // global scope
function total(num1, num2) {
const result = num1 + num2; // function scope
if (true) {
var result1 = num1 * num2; // function scope (var)
}
console.log(result1); // accessible
console.log(person); // global access
}
total(10, 20);
console.log(result); // ❌ Error, function scopeTakeaways
resultis not accessible outside the function.result1is accessible inside the function becausevaris function‑scoped.
What is Hoisting?
Hoisting is JavaScript’s behavior where variable and function declarations are moved to memory at the beginning of the execution phase.
In other words
Before your code runs, JS prepares memory for all declared variables and functions.
Important points
var→ hoisted and initialized asundefinedlet/const→ hoisted but not initialized (they stay in the Temporal Dead Zone)- Function declarations → fully hoisted
Common misconception
Hoisting does not literally move code to the top; it’s a memory‑preparation process.
Hoisting Example
console.log(a); // undefined
var a = 10;Internally, JavaScript interprets it as:
var a;
console.log(a); // undefined
a = 10;Using let or const
console.log(b); // ❌ ReferenceError
let b = 10;This error occurs because let/const are hoisted but not initialized, creating the Temporal Dead Zone (TDZ).
What are Closures?
A closure is when a function “remembers” variables from its outer scope even after the outer function has finished executing.
Simply:function + its surrounding environment = closure
Why closures are useful
- Maintain private data
- Keep state between function calls
- Widely used in real‑world JS (event handlers, React hooks, etc.)
Closure Example
function total() {
let counter = 0;
return function() {
counter++;
console.log(counter);
};
}
// Usage:
const result1 = total();
result1(); // 1
result1(); // 2
const result2 = total();
result2(); // 1
result1(); // 3Key points
counteris not global.- The inner function remembers its value.
- Each call to
total()creates a new memory instance.
Lexical Scope (The backbone of closures)
function outer() {
let a = 10;
return function inner() {
console.log(a);
};
}The inner function is declared inside the outer function, so it can access variable a. This is lexical scope, which enables closures to work.
How These Concepts Connect
- Scope → defines where a variable lives.
- Lexical Scope → defines what variables a function can access based on the written code.
- Closure → allows functions to “remember” variables from outer scopes.
All three work together in JavaScript!
Summary
- Scope → variable boundaries.
- Hoisting → memory preparation before execution.
- Lexical Scope → determines access based on code structure.
- Closure → functions remember outer data.
Final Thought
Many unexpected behaviors in JavaScript happen because these concepts are unclear.
Once scope, hoisting, lexical scope, and closures are understood, JavaScript becomes predictable and much easier to work with.
Tags: #webdevelopment #frontend #closure #hoisting #scope #lexicalscope #learntocode