使用JavaScript数组,我可以使用单个赋值将其重置为空状态:
array.length = 0;
这使得数组"显示"为空并准备重用,据我所知,这是一个单一的"操作" - 即恒定时间.
是否有类似的方法来清除JS对象?我知道我可以迭代它的字段删除它们:
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { delete obj[prop]; } }
但这具有线性复杂性.
我也可以把对象扔掉并创建一个新对象:
obj = {};
但是"混杂"创建新对象会导致IE6上的垃圾收集问题.(如此处所述)
那么,冒着让事情变得太容易的风险......
for (var member in myObject) delete myObject[member];
......在一行代码中用最少的可怕括号清理对象似乎非常有效.所有成员都将被真正删除,而不是留下垃圾.
显然,如果你想删除对象本身,你仍然需要为它做一个单独的delete().
我认为,对你的问题的简短回答是否定的(你可以创建一个新对象).
在这个例子中,我认为将长度设置为0仍然会留下垃圾收集的所有元素.
如果它是你经常使用的东西,你可以将它添加到Object.prototype.是的,它的复杂程度是线性的,但是之后不进行垃圾收集的任何东西都将是.
这是最好的解决方案.我知道这与你的问题无关 - 但是我们需要多长时间才能继续支持IE6?有许多活动停止使用它.
如果上面有任何不正确之处,请随时纠正我.
ES5解决方案可以是:
// 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解决方案可以是:
// 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]; }性能
无论规格如何,最快的解决方案通常是:
// 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
应该仅在浅层或普通对象上执行的原因是它遍历原型继承的属性,而不仅仅是可以删除的属性.如果不肯定知道对象是平原,for
有Object.getOwnPropertyNames
是一个更好的选择.
所以回顾一下你的问题:你想尽可能地避免使用IE6 GC bug.该bug有两个原因:
每隔这么多的分配就会发生垃圾收集; 因此,你做的分配越多,运行的GC就会运行;
你在空中获得的对象越多,每次垃圾收集运行所花费的时间就越多(因为它将爬过整个对象列表以查看哪些被标记为垃圾).
导致1的解决方案似乎是:保持分配数量下降; 尽可能少地分配新对象和字符串.
导致2的解决方案似乎是:保持"实时"对象的数量; 一旦你不再需要它们就删除你的字符串和对象,并在必要时重新创建它们.
在某种程度上,这些解决方案是矛盾的:要保持内存中的对象数量较少,将需要更多的分配和解除分配.相反,不断重复使用相同的对象可能意味着在内存中保留更多的对象而不是严格必要的对象.
现在提出你的问题.您是通过创建新对象还是删除其所有属性来重置对象:这取决于您之后要对其执行的操作.
您可能想要为其分配新属性:
如果您立即这样做,那么我建议您立即分配新属性,并先跳过删除或清除.(确保所有属性都被覆盖或删除!)
如果该对象不会立即使用,但会在稍后阶段重新填充,那么我建议删除它或将其指定为null,稍后再创建一个新对象.
没有快速,易用的方法来清除JScript对象以便重用,就好像它是一个新对象 - 而不是创建一个新对象.这意味着你的问题的简短回答是"不",就像jthompson所说的那样.
你可以试试这个.下面的函数将对象属性的所有值设置为undefined.也适用于嵌套对象.
var clearObjectValues = (objToClear) => { Object.keys(objToClear).forEach((param) => { if ( (objToClear[param]).toString() === "[object Object]" ) { clearObjectValues(objToClear[param]); } else { objToClear[param] = undefined; } }) return objToClear; };