JavaScript Closures in Action: Real-World Applications
Tags: webdev, javascript, programming, tutorial
Published: 2024-05-05 17:12:47

If you just started out learning javascript and spends a few month with it, or even if you've used javascript for a while, chances are you probably didn't face an issue that required knowledge of javascript closure, or actually maybe behind the scene you already used closure without realizing it.

Closures are considered an advanced topic in javascript, understanding closures is crucial for writing more complex and efficient JavaScript code, let's start to learn more about it.

## Understanding Closures
Closures occur when a function is defined within another function (the outer function) and has access to variables from the outer function's scope.

As we all know functions in javascript have access to variables outside of their scope.

```
 const c = 10;
 
 const add = (a, b) => {
     return a + b + c; 
 }
 
 console.log(add(1,1))
```
As you can see we accessed variable 'c' even though it is outside of `add` function.

When javascript first created it didn't support classes, so at that time developers used **factory function** which is a function that returns an object not a value, here is a simple example of factory function

```
function createCounter(){
    let value = 0;
    
    function increment(){
        return ++value
    }
    
    return {
        increment    
    }
}
```
Let's create a couple of counters to see what is going on

```
const counter1 = createCounter();
const counter2 = createCounter();

console.log(counter1.increment()); // 1
console.log(counter1.increment()); // 2
console.log(counter2.increment()); // 1
```
Now as you see each counter has its own value and keep tracks of it, but how is javascript doing that?! the answer is **closure**, closure tells us `increment()` function has access to `value` variable, but remember each time `createCounter()` get called we're creating a new `value` variable so each time `incrment()` will get access to its own copy of a `value` variable. 

So we can just call  closure **HIDDEN STATE**, and ofcourse its pretty usefull in object oriented programming.


## Implementing Memoization Funciton with Closure
One of the core concept of web or programming in general is memoization, it is also a technique that applied in dynamic programming, basically memoization is realy just a fancy word for caching, so we are just caching the result of the function so that we don't excute the function if we know the result.

```
const add = (a, b) => {
    return a + b;
}

add(1,2); // Excute
add(1,2); // Excute
add(2,2); // Excute
```
Normally when we call a function javascript will not cache the result for you, it is just calling and excute the function but if we add a memoizaiton it will only excute when the result is changing, 

So here is the solution of creating a memoization function that takes a function as its argument and handle the **HIDDEN STATE** (closure) to track the result of the function's excustion

```
function memoize (fn){
    let cache = {}
    return function(...args){
        const key = JSON.stringify(args);
        if(key in cache) {
            return cache[key]
        }
        cache[key] = fn(...args);
        return cache[key]
    }
}
```
We used `cache` variable as a **HIDDEN STATE** and stored the function parameters as key and result of the function as the value in a **Hash Map**, with that we can use our memoize function like this

```
const add = memoize((a, b) => {
    return a + b;
})

console.log(add(1,2)); // Excute
console.log(add(1,2)); // Doesn't Excute
console.log(add(2,2)); // Excute
```

## Conclusion
In conclusion, closures are a powerful and often misunderstood concept in JavaScript. They allow functions to retain access to variables from their lexical scope, even after the outer function has finished executing. Closures are essential for creating private variables, implementing function factories, and optimizing code through techniques like memoization. Understanding closures is crucial for writing more complex and efficient JavaScript code.