What happens with values in closure? JavaScript - javascript

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:
Without closure:
With closure:
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?

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.

Related

Returned object from a function count as a reference to the closure for the javascript garbage collector?

I'm learning about closures and I want to know a bit about the garbage collector behavior. In the following code:
function valueMaker(name, value) {
var final = {};
final[name] = value;
final[double] = value*2;
return final;
}
first = valueMaker('first', 1);
When I call valueMaker it creates a closure where I have the final object, then, it returns the object.
My question is: The returned object count as a reference to the closure? or JavaScript is smart enough to know when I want to keep the closure alive?
When I call valueMaker it creates a closure
No. There is no function inside valueMaker, so there's no closure anywhere.
A closure was created when the function valueMaker definition itself was evaluated, and that closure will be used when you call valueMaker(). Though it's not even an interesting closure, given that there are no free variables that it would use.

JavaScript Closures and variable reference

I'm reading Cameron's, HTM5 JavaScript & JQuery. In his section on JavaScript and closures he gives this example:
function f2()
{
var i = 0;
return function() {
return ++i;
};
}
When the anonymous function was defined inside function f2 it “closed” over its environment as it existed at that point of time, and kept a copy of that environment. Since the variable i was accessible when the function was declared, it is still available when the function is invoked. JavaScript has realised that the anonymous function refers to the variable i, and that this function has not been destroyed, and therefore it has not destroyed the i variable it depends on.
In this bold section where he writes "JavaScript has realised..." does this mean that when JS identifies a dependency between an enclosed variable (i.e. outside the closure) and a closure, that it retains the reference to the variable for later use, whereas if there was no dependency upon the variable it would be destroyed (garbage collected)? So var i below would be destroyed, whereas var i in the closure example above is not?
function f2()
{
var i = 0;
}
Cameron, Dane (2013-10-30). A Software Engineer Learns HTML5, JavaScript and jQuery: A guide to standards-based web applications (p. 74). Cisdal Publishing. Kindle Edition.
The short answer to your question is 'yes, that is correct' perhaps a longer example will help?
function main() {
var i = 0;
var int = setInterval(
function() {
console.log(++i);
if ( i > 9 ) {
clearInterval(int);
}
}, 100);
}
As per the example you gave, the variable i is referenced from the inner function, and is therefore kept around for as long as that inner function is in use.
In this example, int is also kept alive for the same reason, but here we also demonstrate how the GC will clean up when it can. Once i > 9 the Interval timer is cleared, meaning that there is no longer a reference to the inner function. This then also means that the variables i and int referenced by that inner function are no-longer referenced, meaning that the GC can destroy them all.

Does V8 do garbage collection on individual pieces of a scope?

I'm interested in whether V8 does garbage collection on the contents of individual variables within a scope or whether it only does garbage collection on the entire scope?
So, if I have this code:
function run() {
"use strict";
var someBigVar = whatever;
var cnt = 0;
var interval = setInterval(function() {
++cnt;
// do some recurring action
// interval just keeps going
// no reference to someBigVar in here
}, 1000);
someBigVar = somethingElse;
}
run();
Will V8 garbage collect someBigVar? The closure in run() remains alive because of the setInterval() callback and obviously the cnt variable is still being used so the whole scope of run() cannot be garbage collected. But, there is no actual ongoing reference to someBigVar.
Does V8 only garbage collect an entire scope at a time? So, the scope of run() can't be garbage collected until the interval is stopped? Or is it smart enough to garbage collect someBigVar because it can see that there is no code in the interval callback that actually references someBigVar?
FYI, here's an interesting overview article on V8 garbage collection (it does not address this specific question).
Yes, it does. Only variables that are actually used inside of a closure are retained. Otherwise closure had to capture EVERYTHING that is defined in the outer scope, which could be a lot.
The only exception is if you use eval inside of a closure. Since there is no way to statically determine, what is referenced by the argument of eval, engines have to retain everything.
Here is a simple experiment to demonstrate this behaviour using weak module (run with --expose-gc flag):
var weak = require('weak');
var obj = { val: 42 };
var ref = weak(obj, function() {
console.log('gc');
});
setInterval(function() {
// obj.val;
gc();
}, 100)
If there is no reference to ref inside of the closure you will see gc printed.

Clarification regrading circular reference

I don't think I quite understand this concept.
I get how having stuff that require each other leads to a infinite loop but I don't see how this happens in some examples I view
function setHandler() {
var elem = document.getElementById('id')
elem.onclick = function() {
// ...
}
}
How is this a problem? I just see a element being attached a function on click.
It says there's a reference through the outer LexicalEnvironment - but isn't this occurring once?
Thanks in advance.
How is this a problem?
It was a major problem in early versions of IE 6 as it created "memory leaks" because circular references involving DOM elements led to memory not being released when a page was unloaded, so they consumed more and more memory, making the browser less responsive. There's a good article here.
In regard to the particular pattern in the OP, the circular reference is easily avoided:
function setHandler() {
var elem = document.getElementById('id')
elem.onclick = function() {
// ...
}
// Break circular reference
elem = null;
}
JavaScript uses something called lexical scoping. Scopes
define what variables are visible in a certain context (corollary: they define what variables are no longer visible to anyone and may be garbage collected safely)
are created for every function (every time you use the keyword, a new scope is created)
can be nested (because functions can be nested)
are persisted for every function (when you call a function it is guaranteed that it can see all variables in all scopes (!) that were available when it was created)
That means:
// +- global scope
// |
function setHandler() { // |+- scope for setHandler()
// || sees: own, global
var elem = document.getElementById('id'); // ||
// ||
elem.onclick = function() { // ||+- Scope for anonymous function
// ... // ||| sees: own, setHandler, global
} // |||
} // ||
// |
Now the anonymous function you assign to onclick can see the variables elem and setHandler and everything from the global scope.
If the element is destroyed (removed from the DOM), the garbage collector considers what variables went out of scope. A less advanced garbage collector might do this by keeping a reference count for any in-memory object and clean up that object (free the memory) when the reference count reaches zero.
Now the anonymous click handler function cannot be cleaned up because it holds a reference to elem (via the scope) which in turn holds a reference to the anonymous function (via its onclick property). The reference count for both objects stays at 1 because the two refer to each other.
Note point 4 from above: Scopes are persistent, so the "lexical environment" of setHandler() is kept alive even though program execution has already left that function - because it is needed by the anonymous inner function. (This is called "closure" and is one of the cornerstones of JS.)
Modern garbage collectors can spot that situation and clean up the event handler appropriately, but notably old versions if IE misbehaved and leaked the memory.

Is a function return necessary to be called a Closure

Hey i came across this video on youtube http://www.youtube.com/watch?v=KRm-h6vcpxs
which basically explains IIFEs and closures. But what I am not understanding is whether i need to return a function in order to call it a closure.
E.x.
function a() {
var i = 10;
function b() {
alert(i);
}
}
in this case can i call it a closure as it is accessing the 'i' variable from the outer function's scope or do i need to return the function like this
return function b(){alert(i);}
A closure is simply a function which holds its lexical environment and doesn't let it go until it itself dies.
Think of a closure as Uncle Scrooge:
Uncle Scrooge is a miser. He will never let go of his money.
Similarly a closure is also a miser. It will not let go of its variables until it dies itself.
For example:
function getCounter() {
var count = 0;
return function counter() {
return ++count;
};
}
var counter = getCounter();
See that function counter? The one returned by the getCounter function? That function is a miser. It will not let go of the count variable even though the count variable belongs to the getCounter function call and that function call has ended. Hence we call counter a closure.
See every function call may create variables. For example a call to the getCounter function creates a variable count. Now this variable count usually dies when the getCounter function ends.
However the counter function (which can access the count variable) doesn't allow it to die when the call to getCounter ends. This is because the counter function needs count. Hence it will only allow count to die after it dies itself.
Now the really interesting thing to notice here is that counter is born inside the call to getCounter. Hence even counter should die when the call to getCounter ends - but it doesn't. It lives on even after the call to getCounter ends because it escapes the scope (lifetime) of getCounter.
There are many ways in which counter can escape the scope of getCounter. The most common way is for getCounter to simply return counter. However there are many more ways. For example:
var counter;
function setCounter() {
var count = 0;
counter = function counter() {
return ++count;
};
}
setCounter();
Here the sister function of getCounter (which is aptly called setCounter) assigns a new counter function to the global counter variable. Hence the inner counter function escapes the scope of setCounter to become a closure.
Actually in JavaScript every function is a closure. However we don't realize this until we deal with functions which escape the scope of a parent function and keep some variable belonging to the parent function alive even after the call to the parent function ends.
For more information read this answer: https://stackoverflow.com/a/12931785/783743
Returning the function changes nothing, what's important is creating it and calling it. That makes the closure, that is a link from the internal function to the scope where it was created (you can see it, in practice, as a pointer. It has the same effect of preventing the garbaging of the outer scope, for example).
By definition of closure, the link from the function to its containing scope is enough. So basically creating the function makes it a closure, since that is where the link is created in JavaScript :-)
Yet, for utilizing this feature we do call the function from a different scope than what it was defined in - that's what the term "use a closure" in practise refers to. This can both be a lower or a higher scope - and the function does not necessarily need to be returned from the function where it was defined in.
Some examples:
var x = null;
function a() {
var i = "from a";
function b() {
alert(i); // reference to variable from a's scope
}
function c() {
var i = "c";
// use from lower scope
b(); // "from a" - not "c"
}
c();
// export by argument passing
[0].forEach(b); // "from a";
// export by assigning to variable in higher scope
x = b;
// export by returning
return b;
}
var y = a();
x(); // "from a"
y(); // "from a"
The actual closure is a container for variables, so that a function can use variables from the scope where it is created.
Returning a function is one way of using it in a different scope from where it is created, but a more common use is when it's a callback from an asynchronous call.
Any situation where a function uses variables from one scope, and the function is used in a different scope uses a closure. Example:
var globalF; // a global variable
function x() { // just to have a local scope
var local; // a local variable in the scope
var f = function(){
alert(local); // use the variable from the scope
};
globalF = f; // copy a reference to the function to the global variable
}
x(); // create the function
globalF(); // call the function
(This is only a demonstration of a closure, having a function set a global variable which is then used is not a good way to write actual code.)
a collection of explanations of closure below. to me, the one from "tiger book" satisfies me most...metaphoric ones also help a lot, but only after encounterred this one...
closure: in set theory, a closure is a (smallest) set, on which some operations yields results also belongs to the set, so it's sort of "smallest closed society under certain operations".
a) sicp: in abstract algebra, where a set of elements is said to be closed under an operation if applying the operation to elements in the set produces an element that is again an element of the set. The Lisp community also (unfortunately) uses the word "closure" to describe a totally unrelated concept: a closure is an implementation technique for representing procedures with free variables.
b) wiki: a closure is a first class function which captures the lexical bindings of free variables in its defining environment. Once it has captured the lexical bindings the function becomes a closure because it "closes over" those variables.”
c) tiger book: a data structure on heap (instead of on stack) that contains both function pointer (MC) and environment pointer (EP), representing a function variable;
d) on lisp: a combination of a function and a set of variable bindings is called a closure; closures are functions with local state;
e) google i/o video: similar to a instance of a class, in which the data (instance obj) encapsulates code (vtab), where in case of closure, the code (function variable) encapsulates data.
f) the encapsulated data is private to the function variable, implying closure can be used for data hiding.
g) closure in non-functional programming languages: callback with cookie in C is a similar construct, also the glib "closure": a glib closure is a data structure encapsulating similar things: a signal callback pointer, a cookie the private data, and a destructor of the closure (as there is no GC in C).
h) tiger book: "higher-order function" and "nested function scope" together require a solution to the case that a dad function returns a kid function which refers to variables in the scope of its dad implying that even dad returns the variables in its scope cannot be "popup" from the stack...the solution is to allocate closures in heap.
i) Greg Michaelson ($10.15): (in lisp implementation), closure is a way to identify the relationship betw free variables and lexical bound variables, when it's necessary (as often needed) to return a function value with free variables frozen to values from the defining scope.
j) histroy and etymology: Peter J. Landin defined the term closure in 1964 as having an environment part and a control part as used by his SECD machine for evaluating expressions. Joel Moses credits Landin with introducing the term closure to refer to a lambda expression whose open bindings (free variables) have been closed by (or bound in) the lexical environment, resulting in a closed expression, or closure. This usage was subsequently adopted by Sussman and Steele when they defined Scheme in 1975, and became widespread.

Categories

Resources