(without closures)
var count = 0;
function increment(){
count++;
}
in this code, anyone can access count and change it.
(with closures) -> put everything into a function
function counter() {
var count = 0;
function increment(){
count++;
}
}
console.log(count); // this will give referenceError as count can't be accessed.
(inc with function using closure)
function counter() {
var count = 0;
return function increment(){
count++;
console.log(count);
}
}
var counter1 = counter(); //counter fun has closure with count var.
counter1(); // increments counter
Above code is not good and scalable for say, when you plan to implement decrement counter at a later stage.
To address this issue, we use constructors
Adding decrement counter and refactoring code:
function Counter() { //constructor function. Good coding would be to capitalize first letter of ctor fun.
var count = 0;
this.incrementCounter = function(){ //anonymous function
count++;
console.log(count);
}
this.decrementCounter = function(){
count--;
console.log(count);
}
}
var counter1 = new Counter(); // new keyword for ctor fun
counter1.incrementCounter();
counter1.incrementCounter();
counter1.decrementCounter();
// returns 1 2 1
function a() {
var x = 0;
return function b() {
console.log(x);
}
}
var y = a(); // y is a copy of b()
y();
Once a() is called, its element x should be garbage collected ideally. But fun b has closure over var x. So mem of x cannot be freed.
Like this if more closures formed, it becomes an issue. To tacke this, JS engines like v8 and Chrome have smart garbage collection mechanisms.
Say we have var x = 0, z = 10 inabove code. When console log happens, x is printed as 0 but z is removed automatically.