持有对象属性的引用会阻止对象被垃圾回收吗?

4

假设我有一个对象:

var o1 = {
    someKey: 'value'
};

还有一个引用第一个对象的对象:

var o2 = {
    o1Ref: o1
};

还有一个第三个对象,它引用了第一个对象上的一个属性:

var o3 = {
    o1propRef: o1.someKey
};

接下来,假设o2被垃圾回收了。那么,在o3上对o1.someKey的引用是否会阻止o1被回收?

同时,假设o1更大一些,比如:

var o1 = {
    someKey: 'value',
    someBigValue: Buffer(2000000)
};
< p > o1 的未被引用的部分是否可以被收集,或者对象整体被收集?似乎第二个版本的 o1 中,o3 只是保持 o1.someKey 和 o1.someBigValue 可以被释放。同时,我确实意识到这可能因不同的实现而异。如果是这种情况,通常如何考虑最好呢?< /p >
1个回答

3

o1.someKeyo3中的引用是否会阻止o1被回收?

不会,因为根本不存在(一个引用)。你只有一个从创建对象时复制的o1.someKey的值,而不是对o1.someKey属性的引用。 (JavaScript没有对任何东西的引用,除了对象;因此没有属性引用,只有对象引用。)

通过操作可以看到你仅仅获取了初始化时的值:

var o1 = {
    someKey: 'value'
};

var o3 = {
    o1propRef: o1.someKey // (It's not a property reference, it's a copy of the value, but I left the name alone)
};

console.log(o3.o1propRef);  // "value"
o1.someKey = "updated value";
console.log(o3.o1propRef);  // "value"
console.log(o1.someKey);    // "updated vale"

为了防止o1被垃圾回收,需要让o3持有对o1的引用(或者对间接引用o1的对象进行引用)。仅仅从o1.someKey获取值并不能建立任何引用关系。

谢谢T.J.——这正是我怀疑的。我一直想删除我的“引用”使用,因为我知道JS通过值传递东西,但我又想,也许过时了,JS实现采用“引用计数”? - Dmitry Minkovsky
另外,我刚刚访问了你的个人资料(声望非常高,哇),并注意到这个答案:https://dev59.com/42855IYBdhLWcg3weEKJ#4324162。我会阅读的! - Dmitry Minkovsky
@dimadima:你是对的,JavaScript 中的所有东西都是按值传递或分配的。没有按引用传递或分配。有一种值叫做对象引用,它引用对象。但它仍然是一个值。就像指向对象所在大查找表的索引一样。无论实现使用引用计数还是其他技术都无关紧要,因为你只是获取 o1.someKey 的值,而不是任何引用它的方式。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接