Disclaimer
This article is originally based on my understanding of this concept. No guarantee on the accuracy.😅
The closure is a kind of intimidating concept for people new to javascript.
I think it’s necessary to clarify some concept of execution context (EC) and scope before approaching ‘closure’ itself.
Javascript has 3 types of scope (after ES6)
block scope
1
2
3
4{
let a = 0;
}
console.log(a) // ReferenceError: a is not definedFunction scope
Global scope
whenever you’re trying to call/use a variable, the engine would find it along the scope chain.
If the engine detects that a variable would not be called after the function execution context was removed from the call stack, it would junk the variable (garbage collecting) and free the memory.
The [[scope]] is determined during function declarartion.
All code is executed in their execution context: global EC or function EC.
EC can be abstracted as an object which includes variable object, scope chain, and this value.
Whenever a function is called, its EC would be pushed to the top of the call stack. And all the VO are activated as activation objects. When all the code inside the function is executed or returned, the EC was destroyed. Next time if the same function is called again, a new EC would be created.
The function EC has two phases: creation phase and execution phase.
The creation phase is when the VO and ‘this’ are created, and the scope chain is initialed by [[scope]]
The execution phase is when the value of each object/variable is assigned and determined.
A classic interview question:
1 | for (var i=1; i<=2; i++) { |
Expected: 0,1,2
Print: 3,3,3
Some ways to fix this:
1 | for (var i=1; i<=2; i++) { |
1 | for (var i=1; i<=2; i++) { |
- employing block scope
1 | for (let i = 0; i <= 2; i++) { |
1 | for (let i=1; i<=2; i++) { |
Application of the concept of closure
- Singleton Design Pattern
1 | var Logger = (function () { |
Private property in constructor function
1
2
3
4
5
6
7
8
9function Count() {
let n = 1; //👈
this.sum = function () {
console.log(++n);
};
}
let a = new Count();
a.sum();
Reference:
Javascript You Don’t Konw
Professional JavaScript for Web Developers