这个范围/闭包何时在javaScript中被垃圾收集?

时间:2016-05-22 17:52:10

标签: javascript garbage-collection closures

我正在做一个经过范围/闭包的课程,并简要提到垃圾收集。在课程期间提出了一个问题:

  

范围保持多久?答案是 - 直到   已经不再有任何参考。是的,所以我们基本上说了什么   是的,闭包有点像隐藏范围对象的引用。   所以,只要有一些功能仍然有一个关闭   范围,该范围将保持不变。但一旦关闭   消失,范围可以收集垃圾。 "

var sum = function sumHndlr(x, y) {
    if (y !== undefined) {
        return x + y;
    } else {
        return function(y) {
            return x + y;
        }
    }
}

所以对我来说,对闭包的引用就是我们将函数赋值给sum变量,但是它不会意味着它会永远存在,或者我不理解js在js中的执行方式关于编译器解析器等?

1 个答案:

答案 0 :(得分:1)

非常简单,垃圾收集是Javascript解释器/虚拟机的后台进程,可自动释放程序不再需要的对象的内存。

例如,因为您将其视为事件侦听器:当您从某个事件调度程序中删除事件侦听器(通常是一个函数)时,程序的其他任何部分都可能没有对事件侦听器的引用。因此,垃圾收集器可以并且将(在某个未知时间)释放事件监听器所占用的内存。

由于闭包引用了一个scope对象,为了对一个闭包进行垃圾收集,它不仅需要不引用,还需要范围。

如果我修改你的例子:

/* some stuff ... */
function add10(a) {
  var adder = function (x) {
     return function(y) {
       return x + y;
     }
  }

  var sum = adder(10); //creates a closure
  return sum(a);
}

var thirty = add10(20);

/* Some more stuff ... */

在调用add10之后,即使程序继续执行更多内容,垃圾收集器也可以释放与闭包sum关联的内存,因为它不再被引用,是与之相关的范围。

而在这个例子中:

/* some stuff ... */
function add10AndGet20Adder(a) {
  var adders = function (x, y) {
     return [function(z) {
       return x + z;
     }, function(z) {
       return y + z;
     }]
  }

  var sums = adders(10, 20); //creates a closure
  return [sums[0](a), sums[1]];
}

var result = add10AndGet20Adder(50);
var sixty = result[0];
var add20 = result[1];

/* Some more stuff ... */

执行更多内容时,sums[0]不再被引用, add20sums[1])仍然引用引用{{}的范围1}}和x因此,y中的两个闭包都不能被垃圾收集器释放,直到程序引用sums

我希望这更加清晰,尽管这些示例当然与实际代码无关。实际上,只有在开发具有复杂闭包使用的长期程序(例如单页面应用程序或nodeJS服务器)时,才需要担心这一点。否则,闭包的内存使用不太可能成为问题。

这个SO问题提供了有关Javascript垃圾收集的更多详细信息:What is JavaScript garbage collection?