Closure in JavaScript Example
What is Closure?
According to Mozilla docs, closure is the combination of a function bundled together with references to its surrounding state. Closures are created every time a function is created, at function creation time. So, in this article, we will learn the closure in javascript with example code.
Now I refer to MDN docs for most things related to JavaScript but this definition doesn’t really help you understand what a closure is with the knowledge of Javascript we have so far.
Step 1:
function outer(){
let counter = 0;
function inner(){
counter++;
console.log(counter);
}
inner();
}
outer();
output: 1
- In the above code, we defined a function called “outer()” within the function body we declare a variable “counter” and initialize it to ‘0’.
- We also defined a nested function called “inner()”, within that “inner” function we increment the value of “counter” and then log that value.
- After the function definition, we invoke the “inner()” function inside the “outer” function.
- Finally, we invoke the “outer()” function.
We got the output as 1. This should be clear by now because of how nested functions scope works in JS. When the variable “counter” is encountered within the “inner()” function the JS engine checks if “counter” is present in the “inner()” function scope. If it is not present, then it checks the “outer()” function scope. The variable is present in the “outer()” function, so it increments the “counter” value by 1 and then the new value is return to the terminal which is 1.
Step 2: Now let’s invoke the outer() function twice outside the outer() function.
function outer(){
let counter = 0;
function inner(){
counter++;
console.log(counter);
}
inner();
}
outer();
outer();
Output:
See the output is 1 & 1. Because with every new invocation of the function a temporary memory is established and we have a new “counter” variable initialized to 0 and then incremented. Hence, every “outer()” function call will always print 1 to the console. If this is clear, let’s move on to a slight variation of this code.
Example for Closure
Step 3: At the moment we define the inner function and invoke it within the outer() function. We don’t necessarily want to invoke the inner() function instead we can return the function and invoke it at a later point in time. In JavaScript, it is possible to return a function from other functions. To return the inner() function, we can assign the result of invoking the outer() function to a variable called “fn”. And then, we invoked the fn function twice.
function outer(){
let counter = 0;
function inner(){
counter++;
console.log(counter);
}
return inner;
}
const fn = outer();
fn();
fn();
Output:
Remember all we are doing is instead of executing the inner() function from within the outer() function, we are returning it and invoking the ‘fn’ function twice. See the output is 1 &2. We would expect the output to be 1 & 1 but we got 1 & 2. Because of the concept of closures in Javascript. Now I mentioned that closure is created when a function is returned from another function.
How closures work in JS
In JavaScript, when we return a function from another funciton, we are effectively returning a combination of the function definition along with the function’s scope. This would let the function definition have an associated persistent memory that could hold onto live data between executions. That combination of the function and its scope chain is what is called closure in Javascript. With this definition in mind, you can try to break down the example we have at hand.
See the Closure Example in Javascript, we are returning the inner() function from the outer() function. It returns out in such a scenario JS doesn’t just return the inner() function. It returns the inner() function as well as its scope. In our above example, the function scope has just one variable called counter, which is initialized to 0. So, we have function inner() bundled together with a variable counter which is together termed as a closure. In such situations, the function persists or remembers the value of the counter variable. So, we invoke the ‘fn’ function for the first time, when the counter is incremented to 1 and the value is returned to the terminal. But the ‘fn’ function though remembers that the counter value is 1. So, next time it increments the counter value to 1 + 1=2. That is the reason, we see outputs 1 & 2. And that is how closures work in Javascript.
Conclusion
The key point to keep in mind is that with closures an inner function has access to variables in the outer function scope even after the outer function has finished execution. So, this is a little difficult to understand as a beginner. My advice is to re-read the concept two or three times, it will definitely make sense.