匿名JavaScript对象会占用内存吗?

时间:2015-05-20 01:50:32

标签: javascript

如果我有以下代码:

var a = {a:1,b:2,c:3} ['a']
var b = {a:1,b:2,c:3} ['b']

我创建了两个匿名JavaScript对象。匿名JavaScript对象会占用内存吗?或者他们立即收集垃圾?

3 个答案:

答案 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']; } 。问题是它何时超出范围,在这种情况下发生在函数的末尾。