Reputation: 38209
I've seen a really cool explanation of closure. So in my view closure is a way to store data somewhere. Let's see examples of closure and example without closure:
Without closure:
function F1(x,y)
{
var z=5;
function F2(){
console.log('x='+x+'y='+y+'z='+z);
}
F2();
}
F1(1,2)
With closure:
function F1(x,y)
{
var z=5;
function F2(){
console.log('x='+x+'y='+y+'z='+z);
}
return F2();
}
var p=F1(1,2)
p();
I've understood that in closure when F1() finishes its work, then F1() clears connection to the store where values of F1 are kept. But F2() still keeps the reference to the store of values.
Let's see images:
I would like to know what happens in memory. I have little knowledge of C# and that reference types are reason to create objects in heap for each reference type. My question is how is it possible to store values of F2() if values of F1() are already garbage collected?
I mean what happens in memory - how many are objects created?(JavaScript creates objects on the heap like C#?) or maybe JavaScript just uses stack to store values of functions?
Upvotes: 0
Views: 400
Reputation: 92334
Every time you call a function, a new activation context containing the local variables is created. If inner functions use any of those variables, the activation context is saved (in a closure) so the local variables can be accessed outside of that function.
There is only one closure created per activation context (function call). That is,
// One closure is created every time you call doSomething
// The loop in doSomething creates a single closure that is shared
// by all the divs handlers (or all the handlers point to the same function
// instance and its closure)
function doSomething(divs) {
for (var i =0; i < divs.length; i++) {
div.onclick = function() {
// Because there is only one closure, i will be the same
// for all divs
console.log('Clicked div, i is' + i);
}
}
}
// One closure here
doSomething([div1,div2,div3]);
// One closure here
doSomething([div9,div10, div11]);
The garbage collector will never garbage collect a closure that still has references to it. As an aside, this was one of the sources for memory leaks. There's often a circular reference between a closure and a DOM element, which kept IE from garbage collecting that closure because it couldn't detect that circular reference between DOM elements and regular JavaScript objects.
Upvotes: 3