11 October 2021
What are Closures?
Functions along with a reference to its lexical environment bundled together are known as closures.
Let’s have a look at a basic example of closures.
- We have a simple function as outerFunc() and inside outerFunc() we have initialized a variable and also declared another function as innerFunc() and logged the value of the variable which was initialized inside outerFunc() and we invoked both the function.
- On executing the above code, it will first search for count inside the innerFunc() and since it won’t find a value it will then move to its parent scope, and then it will log the value of count i.e. 2.
- If we look at source code in the browser and on putting a debugger on the line where we are logging the value of count, We can see Closure inside the scope and it holding the value of the count and pointing to outerFunc.
- Since we have stopped our program inside innerFunc() which apparently holds a value of outerFunc(), JS forms a closure of the outerFunc() and keeps the values that have dependencies later i.e. count in our case.
This was a simple explanation about closures now let’s deep dive into closures.
In the above example, when outerFunc() is assigned to invokeOuter variable, It will return the innerFunc function and the execution context of the outerFunc() will be removed from the call stack. Now after a couple of lines of different code, when we invoke invokeOuter() which contains the innerFunc function, It will still be able to get the value of the count that was present on outerFunc() execution context and that execution context is not present anymore. Here closures are coming into the picture.
- After returning innerFunc() the outerFunc() execution context will pop out from the call stack.
- Whenever a function is returned it always remembers its lexical scope no matter on which execution context is running, in our case when innerFunc() was returned it remembers its lexical scope from where it came.
- In simple words when a function is returned it not only returns those lines of code of that function but it also creates a closure with its lexical environment and returns that also.
- Due to this, when we try to access count inside innerFunc(), it still remembers that count was assigned with a value in its parent scope and that value will be stored as closure.