Demystifying JavaScript Scopes and closures: The Key to smarter Code!

SathvikSathvik
6 min read

Just like cricket has different fielding positions, JavaScript has different scopes that determine where variables can be accessed. And just like a player remembering past experiences to improve their game, closures in JavaScript allow functions to remember variables even after execution.

"Let’s Talk About Scopes & Closures (Without Boring You!)"

In JavaScript, understanding scopes and closures is fundamental and essential for writing efficient and bug-free code. These concepts play a crucial role in variable accessibility, memory efficiency, and ensuring data privacy. Understanding scope is crucial for preventing variable conflicts, encapsulating data, and writing maintainable code.

In this blog, we'll break down scopes and closures with simple explanations and code snippets.

What is Scope?
Scope in JavaScript determines where variables are accessible. Think of it as a set of rules that decide whether you can use a variable in a certain part of your code.

What is a Closure?
A closure is when a function remembers the variables from its outer function, even after the outer function has finished executing.

Think of it like a backpack 🎒 that a function carries, filled with variables from its parent function!


“Okay, I know, this is making you go sleepy. Let’s spice things up with a fun conversation! Consider me as Confused Coder, trying to decode JavaScript scopes and closures, and you as Wise Coder, the guru who knows it all. Let’s begin!”

The Confused Coder vs. The Wise Developer

Confused Coder (CC): Hey, I keep hearing about "scope" and "closure" in JavaScript. What is this sorcery? 🧐

Wise Developer (WD): Ah, young Padawan! Welcome to the world of JavaScript, where variables have boundaries, and functions have memories! 🎩✨ Let’s break it down.


1. Global Scope - The Life of the Party 🎉 🥳

WD: Variables declared outside any function are like the host of a party. Everyone knows them!

var partyHost = "John";  // Global scope

function introduce() {
    console.log("Welcome to the party hosted by " + partyHost);
}

introduce(); // Works fine
console.log(partyHost);  // Also works fine, because it's global

CC: So, partyHost is like the popular guy everyone knows?

WD: Exactly! But beware… too many global variables can create a chaotic party!

2. Function Scope – VIP Lounge 🛋️

WD: Variables declared inside a function stay in that function. They're like guests in a VIP lounge—only accessible inside!

function vipLounge() {
    let secretDrink = "Martini"; // Function scope
    console.log("Inside VIP lounge: " + secretDrink);
}

vipLounge(); 
console.log(secretDrink); // ❌ ERROR! Not allowed outside the VIP lounge

CC: So, variables inside a function are like VIP guests. They can’t just wander outside?

WD: Exactly! Function scope keeps things private and neat.

3. Block Scope - Restricted Zones 🚧

WD: Variables declared using let and const follow block scope. Think of it as restricted zones on a cricket field—only fielders assigned there can stay!

if (true) {
    let fielder = "Slip position"; // Block scope
    console.log(fielder); // ✅ Accessible inside the block
}

console.log(fielder); // ❌ ERROR! Not accessible outside

CC: So, let and const are strict bouncers?

WD: Yep! But var doesn’t care—it sneaks out!

if (true) {
    var cheater = "I'm everywhere!";
}

console.log(cheater); // ✅ Works! Because `var` ignores block scope

CC: Whoa! So, var is like a sneaky guest who somehow gets access to every room?

WD: Exactly! And that’s why we mostly avoid var today!

Understanding var: The Rule-Breaker of Scopes!

Unlike let and const, var doesn’t care about block scope—it only respects function scope. If declared inside a function, it stays locked inside. But if declared elsewhere, it sneaks into the global scope, causing unexpected behaviour.

Example: var Ignoring Block Scope

if (true) {
    var x = "I should be inside, but I escaped!";
}
console.log(x); // ✅ Accessible outside the block (Oops!)

Even though x was declared inside the if block, it still exists outside because var doesn't obey block scope!

Example 1: var Respecting Function Scope

function myFunction() {
    var y = "I am safe inside this function";
}
myFunction();
console.log(y); // ❌ ReferenceError: y is not defined

Here, y stays inside the function and cannot escape—this is function scope in action!

Example 2:

A common mistake is using var inside loops, causing unexpected results due to function scope.

for (var i = 1; i <= 3; i++) {
    setTimeout(() => console.log(i), 1000);
}
// Output after 1 second: 4, 4, 4

Fix it using let, which has block scope:

for (let i = 1; i <= 3; i++) {
    setTimeout(() => console.log(i), 1000);
}
// Output after 1 second: 1, 2, 3

💡 Moral of the Story:
Using var can lead to unintended variable leaks, so prefer let and const for better control! 🚀


Closures: The Function That Never Forgets 🧠

CC: Okay, scope makes sense now! But what’s a closure?

WD: Closures are like an elephant—they never forget! 🐘

Imagine you’re at a café. You order a coffee, and the barista remembers your order even after you step away. That’s a closure—a function remembering the variables from where it was created!

Closures in Action!

function coffeeShop() {
    let order = "Cappuccino"; // This variable is inside coffeeShop()

    return function serveCoffee() {
        console.log("Here's your " + order);
    };
}

const myOrder = coffeeShop(); // The inner function "serveCoffee" is returned
myOrder(); // "Here's your Cappuccino"

CC: Wait… the function serveCoffee() remembers order even after coffeeShop() is done?

WD: Bingo! That’s closure! The function keeps access to the variables from where it was created, even if that outer function has already finished executing.

Closures Are Like Secret Diaries! 📖

function secretDiary() {
    let secret = "I love JavaScript!"; 

    return function revealSecret() {
        console.log("Shh... the secret is: " + secret);
    };
}

const diary = secretDiary();
diary(); // "Shh... the secret is: I love JavaScript!"

CC: So, revealSecret() still knows the secret, even after secretDiary() is gone?

WD: Yes! Closures are like keeping a diary locked away but still being able to read old entries!

Real-World Uses of Closures

CC: Cool! But why do I need closures?

WD: Great question! Closures are used everywhere in JavaScript, like:

1. Data Privacy (Encapsulation) 🔒

function bankAccount() {
    let balance = 1000; // Private variable

    return {
        deposit: function(amount) {
            balance += amount;
            console.log("New Balance: $" + balance);
        },
        withdraw: function(amount) {
            if (balance >= amount) {
                balance -= amount;
                console.log("New Balance: $" + balance);
            } else {
                console.log("Insufficient funds!");
            }
        }
    };
}

const myAccount = bankAccount();
myAccount.deposit(500); // New Balance: $1500
myAccount.withdraw(200); // New Balance: $1300
console.log(myAccount.balance); // ❌ Undefined! Direct access is not allowed

CC: So, the balance is hidden, but I can still update it using the provided functions?

WD: Exactly! Closures help us hide data and prevent direct modification!

2. Function Factories: Creating Multiple Functions with Unique Values 🏭

function greetingGenerator(greeting) {
    return function(name) {
        console.log(greeting + ", " + name + "!");
    };
}

const sayHello = greetingGenerator("Hello");
const sayHola = greetingGenerator("Hola");

sayHello("Alice"); // Hello, Alice!
sayHola("Carlos"); // Hola, Carlos!

CC: Each function remembers the greeting it was created with?

WD: Yep! Closures at work!


Wrapping Up: What Have We Learned? 🎓

Scope determines where variables are accessible (global, function, or block).
Closures allow functions to remember variables from their outer function even after execution.
Closures help with data privacy, function factories, and maintaining state.

CC: This was fun! So, understanding closures makes me a better JavaScript developer?

WD: 100%! Master scopes and closures, and you’ll be writing clean, efficient, and powerful JavaScript! 🚀

0
Subscribe to my newsletter

Read articles from Sathvik directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sathvik
Sathvik