如何快速清除Javascript对象?

使用Javascript数组,我可以使用一个赋值将它重置为空状态:

array.length = 0; 

这使得数组“显现”是空的,可以重复使用,据我所知,这是一个单一的“操作”,即恒定的时间。

有没有类似的方法来清除JS对象? 我知道我可以迭代它的字段删除它们:

 for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } } 

但是这具有线性复杂性。

我也可以扔掉这个物体并创build一个新的物体:

 obj = {}; 

但是,“混杂”创build新对象导致IE6上的垃圾收集问题。 ( 如这里所述 )

我想,你的问题的简短答案是否定的(你可以创build一个新的对象)。

  1. 在这个例子中,我相信设置长度为0仍然留下垃圾收集的所有元素。

  2. 如果你经常使用的话,你可以把它添加到Object.prototype中。 是的,它的复杂性是线性的,但是之后没有做垃圾回收的事情将会是。

  3. 这是最好的解决scheme。 我知道这与您的问题没有关系,但是我们需要多长时间才能继续支持IE6? 有很多活动停止使用它。

如果上面有任何不正确的地方,请随时纠正我。

好吧,冒着让事情变得简单的风险…

 for (var member in myObject) delete myObject[member]; 

…似乎是相当有效的清洁对象在一行代码与至less可怕的括号。 所有成员将被真正删除,而不是留下垃圾。

显然,如果你想删除对象本身,你仍然需要做一个单独的delete()。

ES5

ES5解决scheme可以是:

 // for enumerable properties Object.keys(obj).forEach(function (prop) { delete obj[prop]; }); // for all properties Object.getOwnPropertyNames(obj).forEach(function (prop) { delete obj[prop]; }); 

ES6

而ES6解决scheme可以是:

 // for enumerable properties for (const prop of Object.keys(obj)) { delete obj[prop]; } // for all properties for (const prop of Object.getOwnPropertyNames(obj)) { delete obj[prop]; } 

性能

不pipe规格如何,最快的解决scheme通常是:

 // for enumerable properties var props = Object.keys(obj); for (var i = 0; i < props.length; i++) { delete obj[props[i]]; } // for all properties of an object with proto chain var props = Object.getOwnPropertyNames(obj); for (var i = 0; i < props.length; i++) { delete obj[props[i]]; } // for all properties of shallow/plain object for (var key in obj) { // this check can be safely omitted in modern JS engines // if (obj.hasOwnProperty(key)) delete obj[key]; } 

for..in只能在浅的或纯的对象上执行的原因是它遍历了原型inheritance的属性,而不仅仅是可以删除的属性。 如果不确定对象是否是普通的,那么Object.getOwnPropertyNames是一个更好的select。

因此,要回顾一下你的问题:你想尽可能避免IE6 GC错误的麻烦。 这个错误有两个原因:

  1. 垃圾收集每隔一段时间就会发生一次。 因此,你进行的分配越多,进程GC就会运行;
  2. 你得到的对象越多,“垃圾收集”运行的时间就越多(因为它会抓取整个对象列表,看看哪些对象被标记为垃圾)。

导致1的解决scheme似乎是:保持分配数量下降; 尽可能less地分配新的对象和string。

导致2的解决scheme似乎是:保持“活”对象的数量下降; 一旦你不再需要它们,就立刻删除你的string和对象,并在必要时重新创build它们。

在一定程度上,这些解决scheme是矛盾的:将内存中的对象数量保持较低将需要更多的分配和解除分配。 相反,不断重复使用相同的对象可能意味着将更多的对象存储在内存中,而不是严格需要。


现在为您的问题。 无论是通过创build一个新对象还是删除其所有属性来重置一个对象:这将取决于您之后要使用的对象。

你可能会想分配新的属性:

  • 如果你立即这样做,那么我build议直接分配新的属性,并跳过删除或清除。 (确保所有的属性被覆盖或删除,但!)
  • 如果对象不会立即使用,而是稍后将被重新填充,那么我build议将其删除或将其指定为空,然后再创build一个新对象。

没有一种快速,简单的方法来清除JScript对象以便重新使用,就好像它是一个新对象一样 – 不需要创build一个新的对象。 这意味着你的问题的简短答案是“不”,就像jthompson说的那样。

在ES7中对于期待Object.observe和一般的数据绑定有一些新的想法。 考虑:

 var foo={ name: "hello" }; Object.observe(foo, function(){alert('modified');}); // bind to foo foo={}; // You are no longer bound to foo but to an orphaned version of it foo.name="there"; // This change will be missed by Object.observe() 

所以在这种情况下#2可以是最好的select。

你可以试试这个 下面的函数将对象属性的所有值设置为undefined。 与嵌套对象一起工作。

 var clearObjectValues = (objToClear) => { Object.keys(objToClear).forEach((param) => { if ( (objToClear[param]).toString() === "[object Object]" ) { clearObjectValues(objToClear[param]); } else { objToClear[param] = undefined; } }) return objToClear; }; 

您可以删除道具,但不要删除variables。 delete abc; 在ES5中是无效的(并严格使用)。

您可以将其分配给null以将其设置为删除GC(如果您有其他对属性的引用,则不会)

在对象上设置length属性不会改变任何东西。 (它只是,设置财产)

简单地做:

 myObject = {}; 

这将清除它的价值的对象。