Javascript闭包是否始终保留范围变量?

The*_*ver 2 javascript memory closures

我知道闭包中的代码可以访问范围链中的变量和方法及参数,但是如果它不使用任何一个会发生什么?那些变量仍然保留?

考虑这种情况:

function f(){

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

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

}

var x = f();
Run Code Online (Sandbox Code Playgroud)

变量是否a保留在内存中,即使闭包没有使用它?

谢谢

更新:似乎没有关于'琐碎'关闭的答案.因此,假设每个闭包(即使它什么都不做)可以在内存中保留范围链中的所有方法,包括它们的参数,变量和内部函数(直到闭包被垃圾收集),这是公平的吗?

此外,关于node.js的"可能重复"的问题 - 据我所知node.js仅在基于谷歌的v8 JS引擎的专用环境上运行.在这里,我谈论的是将在任何现代浏览器中运行的Web应用程序(在大多数情况下)

Eri*_*ric 5

当解释器选择释放它占用的内存是一个实现细节 - 没有单一的JavaScript解释器.

请注意,解释器并不总是可以知道变量未使用:

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')
Run Code Online (Sandbox Code Playgroud)

在chrome控制台中进行试验

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
Run Code Online (Sandbox Code Playgroud)

似乎V8正在根据eval的现状进行优化

  • 不,它不仅看起来无辜,而且*是无辜的.`g('a')`和`eval('a')`做不同的评价,[EcmaScript特别介绍了"*直接调用*"的概念](http://es5.github.io/#x15. 1.2.1)为此.`g`将评估全局范围内的代码. (3认同)