我一直不确定封闭器周围的JS垃圾收集规则,所以我想我也可以问......这是一个很好的例子,我很好奇涉及jQuery的$.each
方法:
storeSelection: function() {
var enabledIds = {};
$.each(this.nodes, function(index, node) {
if (node.enabled) {
enabledIds[ node.id ] = true;
}
});
this.selection = enabledIds;
}
上面的snippit当然是对象字面的一部分。所以,我在外部函数的顶部创建了一个新对象,它将在数组中存储已启用项的ID。使用jQuery的.each()
方法,我循环遍历项目数组并记录启用的ID。最后,我将选择存储为父对象的成员。
我的问题涉及从外部范围引用enabledIds
对象的内部函数。由于enabledIds
会一直存在,这是否会阻止收集内部函数?我不会假设,因为它只是一个在内部函数结束时被清除的变量,对吧?为了成为泄漏,我假设内部函数需要对外部对象进行硬引用,如:
$.each(this.nodes, function(index, node) {
this.badIdea = enabledIds;
if (node.enabled) {
enabledIds[ node.id ] = true;
}
});
然而......我对这条规则总是模糊不清。任何帮助消除这种困惑都将不胜感激!
答案 0 :(得分:3)
不,即使你的第二个例子也不足以导致泄密。 badIdea
附加到各个节点,$.each
块将退出并进行垃圾回收。所有现代浏览器都使用“标记和扫描”算法进行javascript垃圾收集,该算法遵循父对子的关联并收集任何“不可达”,即任何这些树无法访问的内容。
答案 1 :(得分:1)
你是对的,来自内部函数(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; };
}();
你不能再访问它,它是垃圾收集的候选者。