Closures in JavaScript.
Tags: javascript, beginners, codenewbie, webdev
Published: 2021-08-25 16:28:13

What is a **Closure**?

A Closure is bundle of a function along with its lexical environment.

In simpler terms, when a function is run, it checks in its surrounding state (lexical environment) and holds on to any variables even after the block in which those variables are has finished executing, if it thinks that it is going to need them in the future.

Here, function holds on to the reference to that variable and not the actual value itself and includes the parent scopes as well.

So, A continuous scope which holds the variables even after it has exited a block after execution so that they can referenced in future is a CLOSURE.


This scope along with is private variables exist as long as the function continues to exist.

Every JavaScript developer has come across closure even though they did not know this concept existed.

Let us go solve a few examples which explain this concept in a better way.

Let us start with a simple one.


```javascript
let outer= function(){
    let a=5,b=20
    function insideOuter(){
        return a+b
    }
    return insideOuter
}



let outputOne=outer()
console.log(outputOne)
console.log(outputOne())



--output on console is ---
ƒ insideOuter(){
        return a+b
    }
25.
```


If you see above we are calling a function which returns another function called **insideOuter**.

We pass this into a variable called **outputOne** so that we can call that whenever needed.

When **outputOne** is called the **insideOuter** function is called which is dependent on the **outer** function scope because a when it is called, it sees the environment in which it was created and not the environment in which it was called.

So, a closure is which is already formed with that block.

But how do we know if it has formed or not? We cant see it right? Actually we can. 

Let us put the execution on hold by placing a *debugger* at **line 10** or at line 4 and lets observe the console.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ztqvyoeb8el9edrf5drg.PNG)

If you observe carefully, at the bottom right it shows that it has formed a closure with **outer** function scope.

Now, As I said this scope will also include the parent scope as well if needed. So, let us add a few more steps to the code.

```javascript

let outer= function(){
    let a=5,b=20
    function insideOuter(){
        let c=7.5
        function innerMost(){
            return (a+b+c)
        }
        return innerMost        
    }
    return insideOuter
}




let outputOne=outer()
console.log(outputOne)

let outputTwo=outputOne()
console.log(outputTwo)

let result=outputTwo()
console.log(result)

```

Here, we have **outer** which returns **insideOuter** function.
As we know this forms closure. When the return function is called that returns another function **innerMost**.

This **innerMost** first forms closure with **insideOuter** scope. But that scope does not have all the variables needed for it to run independently right. So, it looks above another level and when found it forms a closure.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/91ypjrph817a9ewo9857.PNG)

In the above image, we can clearly see that since the **innerMost** is forming closure with both **insideOuter** and **outer** function environment/scope. 

So, even after 1000 lines of code when we execute **outputTwo** as a function, the scope still persists.

Here is such an example. 

![c3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmyoi1sp0lk792wl8ns6.PNG)

Let us look at another example.

```javascript

let multiplier =factor=>{
    return number=>{
        return number*factor
    }
}


let thrice=multiplier(3)
let thriceOfFive=thrice(5)
console.log(thriceOfFive)


---output on console ---
15

```

Here, **Anonymous** function forms closure with **multiplier** function environment and holds onto the variable **factor**.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3l6j30d1u1f3xzxxj5m.PNG)

Let us look at another example.
This is one of the most asked questions in interviews on Closure.
**setTimeout** function can mess the way closures are formed. Actually it will make us confusing.

```javascript


for(var i=0;i<3;i++){
    function one(){
        console.log(`${i} from function one`)
    }
    const two=()=>{
        console.log(`${i} from function two`)
    }
    setTimeout(two,1000)
    one()
}


```

Here, We created a for loop and for every iteration we are calling the functions defined inside and logging the output.

The job of the functions is simple. They need to log a statement with **i** variable value at that particular point of time.

Take a good look at the code and guess the output.

You might think that the output might be this. I thought the same as well

```javascript

0 from function two
0 from function one
1 from function two
1 from function one
2 from function two
2 from function one

```

Or something else, but the actual answer is this.

![c5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n4c0ey1xlyablptm5856.PNG)

But why? What exactly happened? Why did we even get the output like this?

This is because of two reasons.

First one is that JavaScript does not wait for the time declared on **setTimeout** it instead takes timer along with the data that needs to be processed and stores it somewhere and continues with the rest of the program and once the timer expires it processes that part of the data.

And this is what causes the main problem. By the time the timer expires, since JavaScript does not wait, it has already run through the loop and as a result **i** value gets updated while function **two** is relaxing somewhere else function **one** gets executed. 

Second reason is that, since we declared variable ** i** using **var** keyword and that is only function scoped not block scoped. So **i** here is on the global space. So, it does not need to form any closure as it will always be available.

So, since **i** is global, function **two** will point to the same reference and when the timer expires the  **i** value at that particular point of time is logged. 

Then how to we get an output where function **two** holds **i**? Simple. Lets make sure closure is formed. We can do this by making the variable **i** be declared using **let** keyword.

```javascript


for(let i=0;i<3;i++){
    function one(){
        console.log(`${i} from function one`)
    }
    const two=()=>{
        console.log(`${i} from function two`)
    }
    setTimeout(two,1000)
    one()
}


```

Since **let** is block scoped, functions will form a closure with that block. So, now we get the output as follows. 

![c6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qs2v2638wdv8a6y5zep3.PNG)

If you look below, when the variable **i** was declared using **var** it is on global space.

![c7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpgwbqsm1x4ydu3f201s.PNG)


While, when the variable **i** was declared using **let** both functions are forming closure with it. Which means **i** when formed, it points to a new reference for each and every function call.


![c8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg99y7ol9ytnas5xrn4b.PNG)


This is what closures are.

![c0](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uf2rv7lyf408udpnmqu4.jpg)

Think of closure as saving a post on Instagram so that you can reference it later and once you decide its no longer need it you just remove that. The difference is that JavaScript does this job for us. 

Thanks for the read.
Any feedback is highly appreciated.

Happy coding. 🤎