As per the definition of Javascript Developer, Closure is defined as the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). But what is meant by the terms “enclosed”, “surrounding state“, and lexical environment?
No need to worry, we’ll discuss their terms and closure in this article with an example.
Before jumping to closure, let’s understand how javascript works.
Everything in javascript happens inside an “Execution Context”.It’s like a big box in which we have two components.
1) Memory Component:-> where all functions and variables are stored in key-value pairs. “Memory component” is also known as “variable environment”.
2) Code Component:-> place where code is executed one line at a time. This is also known as “thread of execution.
Figure 1
Whenever a javascript file is created, all the variables and functions are stored in the memory component before running the js file only. Variables declared with type var are initialized with the value ‘undefined’ while functions are initialized with the whole function definition only. And after execution of the assigned line, the variables are reassigned with values passed in variables present in that execution context.
In the case of function execution, again a new execution context is created with the name same as a function which will be having its own local memory component and code component.
Figure 2
Here, figure 2 is a snapshot of when our code has executed till line 3 and has not returned a variable. (line 4)
Now, let’s understand the term surrounding state/ lexical environment in the definition of closure.
Lexical environment means variable and function which is present in that scope and variable present over its parent’s environment( parent env refers to the physical place where a function is called).
So, whenever a variable is used in some function that is being returned and it is not declared in that function then it looks for its parent function if that variable is present over there. This whole package refers to closure.
Let’s deep dive into understanding closure with an example.
Figure 3
In figure 3, we are calling function y() using function x(). When function y() is executed a new execution context is created with a memory component as empty as it doesn’t have any variable or function declared in it. So when console.log(“a→”, a) is executed then it looks for the ‘a’ variable in its local execution context but is not found. Then it looks into its parent’s execution context i.e x’s execution context and there it found the variable a declared over there and outputs its value i.e 7.
This property of function y which is binding variable a with its parent’s environment i.e x is known as closure.
Another property of closure is that if a function is returned, then after executing the whole function r (see figure 4), it doesn’t get deleted from its memory, variable t still knows the reference of function s and the value bound to it from where it is present. Therefore after executing the whole function of r. It still remembers the reference of variable b and returns 7 in output (see fig 5)
Figure 4
Figure 5
Use of Closures
- Module Design Pattern
- Function like once
- Memoize
- Set Timeouts
- Maintaining state in the async world
To see the above and execute, attached with this document, follow these steps –
- Unzip the file closure.
- Install node js and vs code in your system.
- Move to this project directory where this folder is present.
- In the terminal, type the ‘node index.js’ command.
Code - index.js //scenario 1 function x(){ var a = 7; function y(){ console.log("a -->",a); } y(); } x(); //scenario 2 --> returning whole function function r(){ var b = 7; function s(){ console.log(b); } return s; } var t = r(); console.log("t -->",t) t() //scenario 3 --> changing value before returning function n function m(){ var c = 7; function n(){ console.log(c); } c = 100; return n; } var p = m(); console.log("p -->",p) p()