How memory stacks work in javascript
When we have code like:
function a(){
var x =0;
this.add=function(){
alert(x++);
}
}
var test = new a();
test.add(); // alert 0
test.add(); // alert 1
test.add(); // alert 2
How it works? Doesn't that mean that the "x" value in a () should be "gone" as soon as test = new a () is finished? The stack contains x should also disappear, right? Or does javascript always keep all stacks ever created, in case they are specified in the future? But that would be nice, wouldn't it?
a source to share
What you see is the closure effect . A function defined inside another function gains access to all variables and those in the scope where it is located - even after the return of the outer function. More details here , but basically the variables (and arguments) in a function all exist as properties of an object (called a "variable object") associated with that function call. Since the function you bound to this.add
is defined in this context, it has a strong reference to that object, preventing garbage collection, which means that the function can continue to access these properties (like variables and function arguments).
You usually hear people say that a function is closed over a variable x
, but it is more complex (and interesting). This is access to the variable object that is being carried over. This has consequences. For instance:
function foo() {
var bigarray;
var x;
bigarray = /* create a massive array consuming memory */;
document.getElementById('foo').addEventListener('click', function() {
++x;
alert(x);
});
}
At first glance, we can see that the click handler only uses x
. So it only has a link to x
, right?
Invalid, a reference to a variable object containing x
and bigarray
. This way the content bigarray
will stick even if the function doesn't use them. This is not a problem (and is often useful), but it highlights the underlying mechanism. (And if you don't really need the content bigarray
in the click handler, you can do bigarray = undefined;
before returning from foo
just for the content to be released.)
a source to share
The word you are looking for is closure.
Creation function
inside another function gives the inner function a a (hidden) reference to the local scope where the outer function was executing.
As long as you keep a copy of yours test
, which has an explicit reference to the function add
, and that function has an implicit reference to the scope created when the constructor function is called a
. This scope has an explicit reference to x
and any other local variables defined in the function. (This includes the value this
and the constructor arguments
- although you cannot access them from the inside add
, as this function this
/ arguments
hides them.)
When you release test
, the JavaScript interpreter can let go x
because there is no way to return a reference to that variable.
a source to share