Understanding Scope, Hoisting, and Closures like a Pro!

Published: (April 5, 2026 at 04:00 AM EDT)
4 min read
Source: Dev.to

Source: Dev.to

Cover image for Understanding Scope, Hoisting, and Closures like a Pro!

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 {} (using let or const)
  • 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 scope

Takeaways

  • result is not accessible outside the function.
  • result1 is accessible inside the function because var is 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 as undefined
  • let / 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(); // 3

Key points

  • counter is 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

0 views
Back to Blog

Related posts

Read more »

Execution Context

Bayangkan Execution Context seperti sebuah dapur. Sebelum kamu memulai memasak mengeksekusi kode, kamu perlu ruang kerja, peralatan variabel, dan resep function...

Spread vs Rest Operators in JavaScript

!Cover image for Spread vs Rest Operators in JavaScripthttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%...