如果我有以下代码:
var a = {a:1,b:2,c:3} ['a']
var b = {a:1,b:2,c:3} ['b']
我创建了两个匿名JavaScript对象。匿名JavaScript对象会占用内存吗?或者他们立即收集垃圾?
答案 0 :(得分:2)
每个匿名对象在用于属性查找时都必须存在,因此在此期间需要占用内存。完成属性查找后,再也没有使用该对象了,所以它变成了垃圾。
无法保证垃圾实际上何时会被收集,因此在这些行运行后,对象仍然可能(并且可能)存在于内存中。但是他们符合条件进行垃圾收集,并且将在未来某些时候收集,当JavaScript引擎需要为其他数据释放内存时。
答案 1 :(得分:0)
下面是垃圾收集的工作原理示例,与您的问题类似,您会注意到o2.a与您的场景类似。还要注意的是,由于对象的一部分仍在使用中,因此整个变量仍在使用中。
var o = {
a: {
b:2
}
};
// 2 objects are created. One is referenced by the other as one of its property.
// The other is referenced by virtue of being assigned to the 'o' variable.
// Obviously, none can be garbage-collected
var o2 = o; // the 'o2' variable is the second thing that
// has a reference to the object
o = 1; // now, the object that was originally in 'o' has a unique reference
// embodied by the 'o2' variable
var oa = o2.a; // reference to 'a' property of the object.
// This object has now 2 references: one as a property,
// the other as the 'oa' variable
o2 = "yo"; // The object that was originally in 'o' has now zero
// references to it. It can be garbage-collected.
// However what was its 'a' property is still referenced by
// the 'oa' variable, so it cannot be free'd
oa = null; // what was the 'a' property of the object originally in o
// has zero references to it. It can be garbage collected.
所以一般来说,我会说,是的,他们仍然会占用记忆。
但是,我还怀疑很多浏览器都足够聪明,可以发现你只在该行上创建了对象,并且只分配了它的一部分,所以没有理由保留整个对象,可以删除它。但通常只要a或b变量在附近就会使用内存。
答案 2 :(得分:0)
表达“匿名JavaScript对象”有点奇怪。 JavaScript对象只是对象,并且本身没有名称。它们可能被或不被其他东西引用,包括但不限于它们被分配到的变量。例如,请考虑以下情况:
function make_getter(obj) { return function(p) { return obj[p]; }; }
var getter = make_getter({a: 1});
此处{a: 1}
是“匿名的”,但由于被关闭,在make_getter
返回并分配给getter
的函数中被引用,只要{ <1}}仍然在范围内,因此对象不能(也不会)被垃圾收集。
对象是否被垃圾收集与是否在某些实时上下文中引用有关,而不仅仅是它是否已分配给变量。它可能被分配给一个变量,但已超出范围;或者它可能没有分配给变量,但仍然存在于某个范围内。
正如其他帖子所提到的那样,实际的GC会在发动机感觉如此,并且你没有或者不需要对它进行控制时发生。
换句话说,下面的两个片段在GC术语中是相同的:
getter
没有人关心您是否碰巧给对象命名function gc1() {
return {a:1, b:2, c:3}['a'];
}
function gc2() {
var o = {a:1, b:2, c:3};
return o['a'];
}
。问题是它何时超出范围,在这种情况下发生在函数的末尾。