Yandex

JavaScript Closures
Lexical Scope, Inner Functions, and Practical Use Cases



What is a Closure in JavaScript?

A closure in JavaScript is a powerful concept that allows an inner function to access the variables of its outer function, even after the outer function has finished executing. This behavior is made possible through JavaScript's lexical scoping rules.

Understanding Lexical Scope

Lexical scope means that a function's ability to access variables is determined by its position in the source code. In other words, inner functions have access to the scope in which they were defined—not necessarily the scope from which they are called.


function outer() {
    let outerVar = "I am from outer";

    function inner() {
        console.log(outerVar);
    }

    return inner;
}

const closureFn = outer();
closureFn();
I am from outer

How Closures Work

When outer() is called, it returns the inner function. Even though outer() has finished execution, its variable outerVar is still accessible to inner()—this is the essence of a closure.

Closures Retain State

Closures can maintain their own private state because they retain access to the variables in their lexical scope.


function counter() {
    let count = 0;

    return function() {
        count++;
        return count;
    }
}

const increment = counter();
console.log(increment()); // 1
console.log(increment()); // 2
console.log(increment()); // 3
1
2
3

Each time increment() is called, it accesses and modifies the same count variable inside counter(). That variable is preserved due to closure.

Real-World Use Case: Data Privacy

Closures are useful when you want to encapsulate data and prevent it from being accessed directly.


function secretHolder(secret) {
    return {
        getSecret: function() {
            return secret;
        },
        changeSecret: function(newSecret) {
            secret = newSecret;
        }
    };
}

const obj = secretHolder("hidden123");
console.log(obj.getSecret()); // hidden123
obj.changeSecret("exposed456");
console.log(obj.getSecret()); // exposed456
hidden123
exposed456

The variable secret is not accessible from outside the function—it’s only accessible via the closure methods.

Closures Inside Loops – A Common Pitfall

Using closures in loops often leads to unexpected behavior. Let’s see why:


for (var i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
3
3
3

Because var is function-scoped, the variable i retains its final value of 3 in each closure. To fix this, use let or an IIFE:

Fix using let:


for (let i = 0; i < 3; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}
0
1
2

Fix using an IIFE (Immediately Invoked Function Expression):


for (var i = 0; i < 3; i++) {
    (function(i) {
        setTimeout(function() {
            console.log(i);
        }, 1000);
    })(i);
}
0
1
2

Closures in Event Handlers

Closures allow each event handler to remember its associated data.


function setupButtons() {
    for (let i = 0; i < 3; i++) {
        const btn = document.createElement('button');
        btn.textContent = 'Button ' + i;
        btn.onclick = function() {
            alert('Clicked button ' + i);
        };
        document.body.appendChild(btn);
    }
}

setupButtons();

Each button, thanks to the closure, correctly remembers its own i value when clicked.

Advanced Example: Partial Application

Closures can be used to create specialized versions of functions with some arguments preset.


function multiply(a) {
    return function(b) {
        return a * b;
    };
}

const double = multiply(2);
const triple = multiply(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15
10
15

Summary: Why Are Closures Important?

  • They enable data encapsulation and information hiding.
  • They help preserve state in asynchronous code and event handling.
  • They’re fundamental to functional programming patterns in JavaScript.

Frequently Asked Questions

Is a closure the same as a function?

Not quite. Every closure is a function, but not every function creates a closure. A closure is formed when an inner function “remembers” variables from its outer lexical scope.

Are closures bad for performance?

Closures use more memory since variables must be retained in the scope chain. But this is usually negligible unless closures are heavily created in performance-critical code.

Can closures be garbage collected?

Yes, as long as there are no more references to the closure or the variables it closes over, they will be garbage collected.

Next Steps

Mastering closures will significantly level up your JavaScript skills. You’ll see closures behind the scenes in libraries, callbacks, event handlers, and more. Practice writing your own closures and observe how scope is preserved!



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

You can support this website with a contribution of your choice.

When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M