Altcademy - a Forbes magazine logo Best Coding Bootcamp 2023

What is closure in JavaScript

Understanding Closure in JavaScript

In the vast universe of JavaScript, there exists a powerful, yet often misunderstood concept known as closure. It's not a new concept, but it is integral to understanding how JavaScript works under the hood. Let's demystify this concept together.

What is a Closure?

In basic terms, a closure is a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. It's like a backpack that a function carries around wherever it goes. This backpack has all the variables that the function saw when it was created.

Let's Visualize with a Code Example

Let's look at a simple example. Suppose we have two functions: an outer function outerFunction(), and an inner function innerFunction(). The innerFunction() is defined within outerFunction() and has access to outerFunction()'s variables.

function outerFunction() {
    let outerVariable = 'I am from outer function!';

    function innerFunction() {
        console.log(outerVariable);
    }

    return innerFunction;
}

let myInnerFunction = outerFunction();
myInnerFunction(); // Outputs: 'I am from outer function!'

In the example above, outerFunction() has a local variable outerVariable and a innerFunction() function which logs the outerVariable. When we call outerFunction(), it returns the innerFunction() and assigns it to myInnerFunction. Now, when we call myInnerFunction(), even though the outerFunction() has finished executing and its context is gone, myInnerFunction() still has access to outerVariable. This is closure in action.

Why are Closures Useful?

Closures are not just an academically interesting part of the language; they have practical, everyday uses in JavaScript. Here are a couple of examples.

1. Data Privacy

Closures can help emulate private methods, a concept from object-oriented programming where certain methods are available only within a certain class and are not accessible from outside the class. JavaScript doesn't natively support private methods, but closures provide a way to achieve this.

function Counter() {
    let count = 0;

    this.incrementCount = function() {
        count++;
        console.log(count);
    };
}

let counter = new Counter();
counter.incrementCount(); // Outputs: 1
counter.incrementCount(); // Outputs: 2

In the example above, count is a private variable that can't be accessed directly from outside the Counter function. The only way to increment count is to use the incrementCount function, which is publicly accessible.

2. Function Factories

Closures can also be used to create function factories. A function factory is a function which returns other functions with specific behaviors.

function greetFactory(greeting) {
    return function(name) {
        console.log(greeting + ', ' + name);
    };
}

let greetInEnglish = greetFactory('Hello');
let greetInSpanish = greetFactory('Hola');

greetInEnglish('Alice'); // Outputs: 'Hello, Alice'
greetInSpanish('Bob'); // Outputs: 'Hola, Bob'

In the example above, greetFactory function generates greeting functions based on the input greeting. Even after greetFactory function finishes execution, the returned functions still have access to the greeting parameter.

Wrapping Up

Closures might seem like a complex and daunting concept, but once you visualize them as a backpack that a function carries around, it becomes less intimidating. Closures are like the Swiss Army knife in JavaScript's toolbox, versatile and practical for many different situations from preserving state to creating private variables. So next time when you're coding in JavaScript, remember, you're not alone, each function brings along its own little backpack of closures. Happy coding!