views:

79

answers:

2

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 does this work? Doesn't that the value of 'x' in a() should be 'gone' as soon as test = new a() is complete? The stack contains x should also be gone as well, right? Or, does javascript always keep all the stacks ever created in case they will be referenced in future? But that wouldn't be nice, would it...?

+4  A: 
T.J. Crowder
Well explained both here and in your post linked. I think this information is very important to know when creating objects in JavaScript. Thanks.
Is a()'s 'variable object' same as a()'s scope? Is variable object just another name for scope?
@user227353: Thanks, glad that helped. No, the variable object and scope are slightly different things. `a()`'s variable object sits at the top of its *scope chain*, and so it's the first thing that unqualified references are resolved against. But if something isn't resolved by `a()`'s variable object, the resolution looks to the next object on the chain, etc., etc. (There's also the `with` construct to avoid^H^H^H^H^H deal with.)
T.J. Crowder
Since functions in javascript are also considered as a 'variable', it make me wonder what else, other than variable object, is inside a scope?
@user227353: Mostly I was just pointing out that the properties on `a()`'s variable object aren't *all* that's in scope for it; the properties on the variable objects of all of its enclosing scopes are in scope for it as well. That's pretty much all you need to worry about from the point of view of using Javascript. But for all the gory details of lexical environment records, binding objects, etc., check out section 10 of the spec. :-)
T.J. Crowder
Thanks, for the info. I will check that out later.
+6  A: 

The word you're looking for is “closure”.

Creating a function inside another function gives the inner function a (hidden) reference to the local scope in which the outer function was running.

As long as you keep a copy of your test, that has an explicit reference to the add function, and that function has an implicit reference to the scope created when calling the a constructor-function. That scope has an explicit reference to x, and any other local variables defined in the function. (That includes the this value and the constructor's arguments — though you can't access them from inside add as that function's own this/arguments are shadowing them.)

When you let go of test, the JavaScript interpreter can let go of x, because there's no way to get a reference back to that variable.

bobince
This answer is very useful, I hope I could accept more than one answer.