JavaScript Scope and Closures: A Simple Guide for Newbies

Hirak MahataHirak Mahata
3 min read

Scope and closures are fundamental concepts in JavaScript that every developer should master. They play a crucial role in controlling variable accessibility and maintaining data privacy. In this article, we will explore scope, different types of scope, closures, and practical use cases.

What is Scope?

Scope determines the accessibility of variables and functions in different parts of the code. JavaScript has lexical scoping, meaning that scope is determined at the time of writing the code, not at runtime.

Types of Scope in JavaScript

1. Global Scope

Variables declared outside any function belong to the global scope and can be accessed anywhere in the code.

let myGlobal = "I am a global variable";

function showMyGlobalVariable() {
    console.log(myGlobal); // Accessible
}

showMyGlobalVariable();
console.log(myGlobal); // Also accessible

2. Function Scope(var)

Variables declared inside a function are only accessible within that function.

note: variables declared using var have function scope, meaning they are accessible only within the function itself.

function myFunction() {
    var insideFunction = "I am inside a function";
    console.log(functionScoped); // Accessible inside the function
}

myFunction();
console.log(insideFunction); // Error: functionScoped is not defined

3. Block Scope (let & const)

Variables declared using let and const have block scope, meaning they are accessible only within the enclosing block {}.

{
    let blockScoped = "I exist only in this block";
    console.log(blockScoped); // Accessible
}

console.log(blockScoped); // Error: blockScoped is not defined

4. Lexical Scope

Lexical scope means that a function can access variables from its outer scope.

function outerFunction() {
    let outerVariable = "Outer Variable";

    function innerFunction() {
        console.log(outerVariable); // Accessible due to lexical scope
    }

    inner();
}

outer();

What is a Closure?

A closure is a function that remembers the scope in which it was created, even after the outer function has finished executing.

How Closures Work?

Closures allow functions to retain access to their lexical scope even when executed outside of their original context.

function increment() {
    let count = 0;
    return function () {
        count++;
        console.log(count);
    };
}

const plusOne = increment();
plusOne(); // 1
plusOne(); // 2

Even though increment has executed, the returned function still has access to count due to closure.

Practical Use Cases of Closures

1. Data Encapsulation and Private Variables

Closures help in creating private variables that are inaccessible from outside the function.

function bankAccount(initialBalance) {
    let balance = initialBalance;

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

const myAccount = bankAccount(100);
myAccount.deposit(50); // Balance: $150
myAccount.withdraw(30); // Balance: $120
console.log(myAccount.balance); // Undefined (closure prevents direct access)

2. Event Listeners

Closures are useful in event handling, where they help retain references to variables.

document.getElementById("btn").addEventListener("click", (function () {
    let count = 0;
    return function () {
        count++;
        console.log(`Button clicked ${count} times`);
    };
})());

3. Currying Functions

Closures help create curried functions where arguments are partially applied.

function multiply(x) {
    return function (y) {
        return x * y;
    };
}

const double = multiply(2);
console.log(double(5)); // 10

Conclusion

Understanding scope and closures is essential for writing efficient JavaScript code. Scope determines variable accessibility, while closures allow functions to retain references to variables even after their parent function has executed. By leveraging these concepts, you can write cleaner, more maintainable, and powerful JavaScript programs.

0
Subscribe to my newsletter

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

Written by

Hirak Mahata
Hirak Mahata