Stale Closures — I underestimated closures

Hello World 🌏
Few months back when I was working in React Class components, I’ve no idea what a stale closure is. Back then here is what I knew about closures:
A closure is a function with some preserved values. the values can be of outer scopes.
The closure is a function that can remember and modify variables from its lexical scope, regardless of execution scope.
Let’s understand closures by a real life analogy.
Suppose you have a magical camera 📷.

The magic is of the camera 📷 is that, any photo 🤳 you take, you can interact with the photo.
Example: You took a photo of a lion 🦁,
Now you have the power
1. to open up the photo and interact with the lion 🦁,
2. you can touch 👆 the lion regardless of your place 🌏 either be in your home 🏠, your grannys home 🏡 or on moon 🌙 .
3. if you apply some filters to the photo, the same filter will get applied to the lion 🐯. Meaning both photo and the lion are connected.
As far as you have your magical camera 📷 you can interact 👆 with the lion 🦁.
Similarly in JavaScript, a function is a magical camera,
If you use a variable which is outside the scope of current function, the snapshot of the variable will be taken.
And the snapshot is not static, just like of the picture of lion. If the value of variable changes, you’ve access to the updated value. Just like you can apply filters to lion, you can update the value of the outside variable.
Consider following code snippet:

In the above example, count
is captured by the returned function from numberOfYug
. As you can see I can read and modify the value.
Let us take another example of async, where I will be calling incrementYug
and still count
variable will be increased by factor of 1.

Now it is pretty much clear that, closure works regardless of there place, and the variables can be accessed outside their execution context.
We can check, if any function has a closure variables or not. Simple do console.dir(functionName)
.

This was all about closures, now let me explain what I missed to learn about closures.
So this was my understanding about closures.
When moved to functional component in React then I started getting old values while working with hooks and specially timers. Firstly I though it is the problem of React but later learned that this is not a problem. This is how closures work. And I was expericencing the situation called Stale Closure.
Basically a stale closure is a function which is preserving an old value of a variable.
The is may occur due to two reasons:
1. Any other function updated a value in which closed over variable is dependent.
2. The function which is holding closure function (parent) is done executing, while the closure is still hold the old value.
Lets consider below code, which is demonstrating Reason 1:

Can you guess what will be printed in console?
.
.
.
In the console Current Yug is 0
will be printed.
How? Due to stale closures.
printYug
is holding message
. And value of message
is dependent on count
.
count
is updated by another function incrementYug
.
Let’s do a console.dir
on logYug
to see what exactly it is holding after calling increaseYug
3 times.

As you can see, the logYug
(printYug) is preserving old values.
So for this problem we have two solution:
1. Change
const message
tolet message
and on everyincrementYug
update the message.2. Move the
message
const insideprintYug.

Now let us see the second reason due to which stale closure condition might occur. The second reason is:
The function which is holding closure function (parent) is done executing, while the closure is still hold the old value.
Consider following code snippet and can you guess what will be printed in console?

.
.
In the console current Yug is 1
will be printed.
The function (incrementYug) which is holding closure function (printYug) is done executing, while we are still keeping the reference of closure function (printYug) which is still holding the old value and still using it.
Here printYug is creating two closures. One with message
and one with count.

In above code every execution of `incrementYug` is returning new instance of printYug
but we are keeping old instance and using it.
For this problem we have two solution:
1. Finding and Using the fresh instance of closure function (This is done by React in case of hooks)
2. Use
count
directly insideprintYug
.

I hope my experience with closure make you learn something new about closures.