参数是否会使JavaScript GC无法收集对象?

时间:2013-03-16 07:40:43

标签: javascript garbage-collection

var person = {
    name: 'John'
};

function Pet1(person) {
    var owner = person.name;
    this.showOwner = function() {
        alert(owner);
    }
}

function Pet2(person) {
    this.showOwner = function() {
        alert(person.name);
    }
}

var pets = [new Pet1(person), new Pet2(person)];

...

pets.splice(0, 1);
pets.splice(0, 1);

上面的代码阻止了JS GC在超出范围或没有更多引用时收集Pet1和Pet2的实例。我所知道的是Pet2,但你不觉得Pet1也阻止了JS GC吗?

2 个答案:

答案 0 :(得分:1)

关于你评论的问题:

  

这个人(在这种情况下是全局的)变量会阻止Pet1和Pet2的实例被垃圾收集(如果超出范围而没有更多的引用)

不,为什么要这样? person没有引用Pet实例,反之亦然。从pets数组中删除对Pet实例的引用后,没有什么可以阻止GC收集它们(假设您的“...”代码不会创建对pets[0]的其他引用}或pets[1])。

答案 1 :(得分:0)

答案是“它取决于”。

就现代引擎而言,如果从系统中的其他地方删除person,它仍然可以被收集,即使它在参数中被提及,因为尽管在封闭内部,它从未被引用过再次,从任何公开的方法。

因此,支持删除示波器残留部分的引擎可以轻松地在该对象上运行GC。

那么,问题是哪些引擎会这样做,以及这些引擎的哪些版本会这样做? 我不确定答案。

只是这是可能的,但可以留在旧的或较小的JS引擎的内存中。

修改

这样想:var pet1 = new Pet1(person); Pet1用人来设置pet1的值 人不知道关于pet1的事情。

var pet2 = new Pet2(person);
pet2具有寻找人的功能,可以读取值 所以即使代码中再也没有提到过人,也无法将其删除,因为pet2可能会调用一个需要查找人的函数...
人们仍然不知道pet2是什么。

当不再需要pet2时,以及从上面的数组中删除它时,以及当引用它的每个变量/ object-property / array-index都删除了它的引用时,包括删除在a中创建的函数它存在的范围,并且引用它,不知何故,它可以被删除,因为NO OTHER CODE正在寻找/挂在pet2上。

一旦pet2消失,人们就不再在其他任何地方使用了。
因此,人可以被标记为收集。

GC是关于什么可以访问的东西 如果其他事情仍在讨论该对象,则不允许删除该对象 一个实例可能依赖于50个参数,并且引用了120个其他外部对象,但如果没有其他人关心 it ,那么该实例仍然可以被收集。