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吗?
答案 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 ,那么该实例仍然可以被收集。