javascript - 这个作用域/闭包什么时候在 javaScript 中被垃圾收集?

标签 javascript garbage-collection closures

我正在上一门类(class),该类(class)介绍范围/闭包并简要提及垃圾收集。在类(class)中提出一个问题:

How long does the scope stay around? And the answer was—until there's no longer any references to it. Yep, so what we basically said was, a closure is kind of like a reference to a hidden scope object. So as long as there's some function that still has a closure over the scope, that scope's going to stay around. But as soon as that closure goes away, scope can get garbage collected. "

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

所以对我来说,闭包的引用是当我们将函数分配给 sum 变量时,但这并不意味着它会永远持续下去,或者我不理解 js 的执行方式关于编译器解析器等?

最佳答案

简而言之,垃圾回收是 Javascript 解释器/虚拟机的后台进程,它会自动释放程序不再需要的对象的内存。

例如,由于您将其视为事件监听器:当您从某个事件派发器中删除事件监听器(通常是一个函数)时,程序的其他部分很可能不会引用该事件监听器。因此,垃圾收集器可以并将(在某个未知时间)释放事件监听器占用的内存。

由于闭包引用了作用域对象,为了对闭包进行垃圾回收,它不仅需要未被引用,还需要作用域。

如果我稍微修改一下你的例子:

/* 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]但是 add20 (sums[1]) 仍然有对引用 xy 的作用域的引用,因此 sums 中的两个闭包都不能被释放垃圾收集器,直到 add20 被程序引用。

我希望这能让它更清楚,尽管这些示例当然与真实代码相去甚远。实际上,只有当你开发一个长期使用闭包的程序(如单页应用程序或 nodeJS 服务器)时,你才需要担心这一点。否则,闭包的内存使用不太可能成为问题。

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

关于javascript - 这个作用域/闭包什么时候在 javaScript 中被垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37377653/

相关文章:

java - Android 4.4.4,创建大量字节数组时,垃圾收集器如何处理?

objective-c - 如何调用接受 block 字典作为 Swift 参数的 Objective-C 函数?

python - Django 管理应用程序 : building a dynamic list of admin actions

javascript - 在 Django 项目中使用 JavaScript 的最合适的方式是什么?

JavaScript indexOf 忽略大小写

java - 我们如何知道一个对象是否被 GC 标记为垃圾?

Java就是这个垃圾收集器

javascript - 如何对一个数组进行排序?

javascript - 选取多个属性

javascript - 函数式编程 : What's the difference between using a closure and using the bind method?