2

I understand that code in closure can access variables & methods & arguments up the scope chain, but what happens if it doesn't use any of them ? do those variables still retained ?

Consider this case :

function f(){

  var a=[];
  for(var i=0;i<1000000;i++) a.push({});

  return function(){
     alert('Hi');
  };

}

var x = f();

Does variable a retained in memory even though the closure does not use it ?

Thanks

UPDATE: Seems there's no answer about 'trivial' closures. So is it fair to assume that each and every closure ( even if it does nothing at all ) may retain in memory all the methods up the scope chain including their arguments , variables and inner functions ( until the closure is garbage collected )?

Also, about the 'possibly duplicate' question about node.js - to my knowledge node.js runs only on a dedicated environment that based on google's v8 JS engine. Here I'm talking about web-apps that will run in any modern browser ( in most cases )

TheZver
  • 1,502
  • 2
  • 14
  • 19
  • 1
    You never can really know… The JS implementation can do as it want. Clever garbage collectors that do statical code analysis *can* collect the values, but there is no guarantee. – Bergi Sep 19 '13 at 00:19
  • possible duplicate of [garbage collection with node.js](http://stackoverflow.com/questions/5326300/garbage-collection-with-node-js) (and its related questions) – Bergi Sep 19 '13 at 00:28
  • Rule of thumb: For (old) engines with dumb garbage collectors better set `a=null` explicitly. – Bergi Sep 19 '13 at 00:41
  • If we are to suppose only relatively new browsers , It this an issue to worry about ? – TheZver Sep 19 '13 at 00:44

1 Answers1

5

When the interpreter chooses to free the memory it occupied is an implementation detail - there is no single javascript interpreter.

Note that it's not always possible for the interpreter to know the variable is unused:

function f() {
    var a = 123

    return function(x) {
        alert(eval(x));  // if there's an eval, we have to hold onto all local variables
    };

}

f()('a')

Experimenting in the chrome console

var e = eval

var f = function(){
    var a = 123;
    
    return function() {
        return eval('a');
    };
};

var g = function(){
    var a = 123;

    return function() {
        return e('a');
    };
};


f()()  // 123
g()()  // ReferenceError

It appears that V8 is making optimizations based on the present of eval

Eric
  • 95,302
  • 53
  • 242
  • 374
  • [this answer](http://stackoverflow.com/a/8694390/102441) sheds a bit more light on what's happening. It'd be nice to see the spec for that. – Eric Sep 19 '13 at 00:33
  • 3
    No, it does not only look innocent but *is* innocent. `g('a')` and `eval('a')` do evaluate differently, [EcmaScript specially introduced the concept of a "*direct call*"](http://es5.github.io/#x15.1.2.1) for this. `g` will eval the code in the global scope. – Bergi Sep 19 '13 at 00:36
  • That's fair. but I'm talking about specifically trivial functions of few lines that only use arguments and/or local variables. Does the new browsers know to handle that and act like It's a global-scope-method ? It's of big importance because I've tones of tiny closures used for quick event-handlers setup ( specifically talking - ExtJs component listeners ) – TheZver Sep 19 '13 at 00:36