使用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。如果它是你经常使用的东西,就创建原型。是的,它在复杂性上是线性的,但以后任何不进行垃圾收集的东西都会是线性的。 这是最好的解决办法。我知道这和你的问题无关,但是我们需要继续支持IE6多久呢?现在有很多运动要求停止使用它。

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

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

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

...用最少的吓人的括号在一行代码中清理对象似乎是相当有效的。所有成员将被真正删除,而不是作为垃圾。

显然,如果你想删除对象本身,你仍然必须为它单独执行delete()。

ES5

ES5解决方案可以是:

// for enumerable and non-enumerable properties
Object.getOwnPropertyNames(obj).forEach(function (prop) {
  delete obj[prop];
});

ES6

而ES6解决方案可以是:

// for enumerable and non-enumerable properties
for (const prop of Object.getOwnPropertyNames(obj)) {
  delete obj[prop];
}

性能

不管规格如何,最快的解决方案通常是:

// for enumerable and non-enumerable of an object with proto chain
var props = Object.getOwnPropertyNames(obj);
for (var i = 0; i < props.length; i++) {
  delete obj[props[i]];
}

// for enumerable 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应该只在浅对象或普通对象上执行的原因是,它遍历原型继承的属性,而不仅仅是自己的可以删除的属性。如果不确定对象是普通的且属性是可枚举的,则使用object。getOwnPropertyNames是一个更好的选择。

有一些新的东西可以让你去思考,去期待。在ES7和一般的数据绑定中观察。考虑:

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号可能是最好的选择。

可以删除道具,但不能删除变量。删除abc;在ES5中无效(并使用strict抛出)。

您可以将其赋值为null以将其删除到GC(如果您有其他对属性的引用,则不会这样做)

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