> From: traunic
> 
> I am looking at 
> http://www.devguru.com/technologies/ecmascript/quickref/var.html
> and the impression I get is that using var will override any 
> previous conflicts but not necessarily clean up after itself 
> (up to the engine to do that, which is not something I like 
> to rely on ;).  If I understand correctly a consistent use of 
> delete should get the same results and hopefully in any environment.

Wade, var in a function creates a local variable. When a function returns,
all of its local variables become free for garbage collection, as long as
there are no other references to those variables elsewhere (i.e. a closure).

In your original example:

> function test(foo){
> bar = foo + 3;
> if(bar < 10){...}
> delete bar;
> }

The bar variable is a global variable, because you did not "var" it inside
the function.

In fact, every global variable is actually a property of the window object.
This means that the window object holds a reference to "bar" - and because
of that reference, bar will never be garbage collected.

When you "delete bar;" you are actually doing "delete window.bar;", which
removes the "bar" property from the window object. If that's the only
reference to the bar object or value, bar is now free for garbage
collection.

But you should be using a local variable instead:

   function test(foo){
      var bar = foo + 3;
      if(bar < 10){...}
   }

Every time you call a function, a temporary, invisible object is created
which holds references to that function call's arguments and its local
variables. One reference to that function call object is created when the
function code is entered, and that reference is deleted when the function
returns. If there are no other references to that function call object, then
it and the references it contains are free for garbage collection.

In the code above, the only references to "foo" and "bar" are in the
temporary function call object, so when the function returns, foo and bar
can be garbage collected.

If there *are* any outside references to any of a function's arguments or
local variables, then the entire function call object is kept around until
all of those references are broken.

Consider this simple case:

   function test(foo) {
      var bar = 0;
      window.bar = bar;
      var boo = { a:1, b:2 };
   }

When you assign "window.bar = bar;" it creates a *second* reference to the
function call object, in the window object. When the function returns, that
reference remains and the function call object cannot be garbage collected.

This affects not only the var variable, but every other local variable in
the function, as well as its arguments. So now, bar, boo, and foo are all
kept in memory until you do:

   delete window.bar;
   // or...
   delete bar;
   // or even...
   window.bar = null;

Any of those remove the remaining reference to the function call object, so
all of the function's variables may now be garbage collected. (The first two
examples remove the window.bar property itself. The third one leaves
window.bar in existence, but it no longer is a reference to the "bar"
variable inside the function - so this still breaks the reference to the
function call object.)

Suppose you need to keep that window.bar reference for a long time, but you
don't really need to have the "boo" object kept in memory after the function
returns. Then you can do:

   function test(foo) {
      var bar = 0;
      window.bar = bar;
      var boo = { a:1, b:2 };
      // do some stuff with boo, then...
      boo = null;
   }

The idea here is a lot like what you were doing with "delete". Even if you
can't "delete boo;" here, you can set it to null, which breaks the reference
to the { a:1, b:2 } object - and this frees *that* object up for garbage
collection even though the function call object with its foo, bar, and boo
properties is still being kept around.

But you don't need to do when there are no outside references:

   function test(foo) {
      var bar = 0;
      var boo = { a:1, b:2 };
   }

In this simple case, foo, bar, and boo can all be garbage collected any time
after the function returns.

BTW, "window.bar = bar;" is a contrived example, of course, but the same
pattern occurs invisibly in many other situations: event handlers and
setTimeout/setInterval callbacks, for instance.

-Mike

Reply via email to