关于闭包中垃圾收集的混淆
confusion about garbage collection among closures
我一直不确定 JS 垃圾收集规则围绕关闭一段时间,所以我想我不妨问问......这里有一个很好的例子,我对涉及jQuery的$.each
方法感到好奇:
storeSelection: function() {
var enabledIds = {};
$.each(this.nodes, function(index, node) {
if (node.enabled) {
enabledIds[ node.id ] = true;
}
});
this.selection = enabledIds;
}
当然,上面的截图是对象文字的一部分。因此,我在外部函数的顶部创建了一个新对象,该对象将在一个数组中存储已启用项的 ID。使用 jQuery 的 .each()
方法,我正在遍历项目数组并记录启用的 ID。最后,我将所选内容存储为父对象的成员。
我的问题涉及从外部范围引用enabledIds
对象的内部函数。既然enabledIds
会留下来,这是否会阻止内部功能的收集?我假设不会,因为它只是一个在内部函数结束时被清除的变量,对吧?要成为泄漏,我假设内部函数需要对外部对象进行硬引用,如下所示:
$.each(this.nodes, function(index, node) {
this.badIdea = enabledIds;
if (node.enabled) {
enabledIds[ node.id ] = true;
}
});
然而。。。我总是对这个规则感到困惑。任何帮助澄清这种困惑将不胜感激!
不,即使是你的第二个例子也不足以导致泄漏。 badIdea
附加到各个节点,$.each
块将退出并被垃圾回收。所有现代浏览器都使用"标记和扫描"算法进行 javascript 垃圾收集,该算法遵循父级到子级的关联并收集任何"无法访问的内容",即这些树之一无法访问的任何内容。
你是
对的,来自内部函数(index
,node
)的变量将被垃圾回收,因为它们不能再被访问了。
在此示例中,是否可以访问bigstr
?
a = function() {
var bigstr = new Array(1000000).join('x');
return function() { return bigstr; };
}();
是的,您可以:a()
,因此不会收集。这个例子呢:
a = function() {
var bigstr = new Array(1000000).join('x');
return function(n) { return eval(n); };
}();
同样,您可以:a('bigstr')
.
但是这个呢:
a = function() {
var smallstr = 'x';
var bigstr = new Array(1000000).join('x');
return function(n) { return smallstr; };
}();
您无法再访问它,它是垃圾回收的候选对象。
相关文章:
- 在underscorejs模板中使用闭包
- setTimeout可以与闭包内的函数一起使用吗
- 附加到原型属性的Do函数没有闭包
- 使用闭包共享构造函数参数
- 使用Google闭包编译器包含一个Ecmascript 6类
- 从js引擎的角度来看闭包和构造函数是如何工作的
- for循环中的JavaScript闭包
- Javascript闭包-如何防止内存泄漏
- 子类访问父类's闭包变量
- 闭包如何具体化数据封装
- Javascript.闭包和dynamic'这'实际上具有约束力
- 构造函数函数闭包变量
- 闭包js框架-将ArrayBuffer转换为字符串
- 如何在Angularjs中重构闭包中的重复代码
- 如果闭包的行为类似于对象,它们是对象吗?(好像不像)
- 对闭包内对象的赋值的行为类似于指针
- jQuery.thoggle()等效于Google闭包
- Swift中的闭包概念类似于Javascript中的闭包
- 将常见的js代码移到依赖于闭包的函数中
- 将变量添加到函数作用域/闭包中.函数相当于窗口对象