326

我对JavaScript的delete运算符有点困惑。采取以下的代码:在JavaScript中删除对象

var obj = { 
    helloText: "Hello World!" 
}; 

var foo = obj; 

delete obj; 

这段代码已被执行之后,objnull,但仍foo指物体酷似obj。我猜这个对象与foo指向的是同一个对象。

这使我困惑,因为我预计写delete obj删除obj指向内存中的对象 - 不仅仅是变量obj

这是因为JavaScript的垃圾收集器正在保留/释放的基础上工作,所以如果我没有任何其他变量指向对象,它会从内存中删除

(顺便说一句,我的测试是在Safari 4进行)

+7

供您参考。 https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator – 2009-04-12 23:37:31

+0

关于delete关键字的完整文章http://webcache.googleusercontent.com/search?q=cache:auElwuFsub0J:perfectionkills.com/理解 - 删除/ +删除+ JavaScript&cd = 2&hl = en&ct = clnk&client = safari – 2012-12-17 23:08:34

+2

上面的链接应该是:http://perfectionkills.com/understanding-delete – johnmdonahue 2013-06-13 19:32:38

回答

412

delete运算符删除只是一个参考,从来没有一个对象本身。如果它确实删除了对象本身,那么其他剩余的引用就会像C++删除那样悬而未决。 (并且访问它们中的一个会导致崩溃,为了使它们全部变为空将意味着在删除每个对象或为每个对象增加内存时需要额外的工作。)

由于Javascript是垃圾收集的,因此不需要删除对象他们自己 - 当无法再引用他们时,他们将被删除。

如果完成对象的引用,那么删除对象的引用会很有用,因为这会为垃圾回收器提供有关可回收内容的更多信息。如果引用保留给一个大对象,这可能会导致它不被回放 - 即使程序的其余部分实际上并未使用该对象。

147

delete命令对普通的变量,只有性没有影响。在delete命令之后,该属性的值不是null,它根本不存在。

如果属性是对象引用,则delete命令将删除属性,但不删除对象。如果垃圾收集器没有其他引用,垃圾收集器将负责处理该对象。

例子:

var x = new Object(); 
x.y = 42; 

alert(x.y); // shows '42' 

delete x; // no effect 
alert(x.y); // still shows '42' 

delete x.y; // deletes the property 
alert(x.y); // shows 'undefined' 

(。经测试,在Firefox浏览器)

47

“隐式声明的变量”是全局对象的属性,因此删除对它们起作用,就像它对任何属性起作用一样。用var声明的变量是坚不可摧的。

1

IE 5到8有一个bug,在主机对象(Window,Global,DOM等)的属性上使用delete会引发TypeError“对象不支持这个动作”。

var el=document.getElementById("anElementId"); 
el.foo = {bar:"baz"}; 
try{ 
    delete el.foo; 
}catch(){ 
    //alert("Curses, drats and double double damn!"); 
    el.foo=undefined; // a work around 
} 

以后如果你需要检查其属性都有其意义完全值使用el.foo !== undefined因为"foo" in el 总是会在IE返回true。

如果你真的需要真正消失的财产......

function hostProxy(host){ 
    if(host===null || host===undefined) return host; 
    if(!"_hostProxy" in host){ 
     host._hostproxy={_host:host,prototype:host}; 
    } 
    return host._hostproxy; 
} 
var el=hostProxy(document.getElementById("anElementId")); 
el.foo = {bar:"baz"}; 

delete el.foo; // removing property if a non-host object 

如果您需要使用与主机API主机对象...

el.parent.removeChild(el._host); 
7

基于@Guffa的回答。我发现下面的方法对我的作品:

var obj = { 
    helloText: "Hello World!" 
}; 

obj = null; 

delete obj; 

通过与obj设置为null首先,你删除了所有对它的引用,那么你完全可以将其删除。

我没有测试它在其他浏览器,但这1.7.0

0

我偶然发现这篇文章在我的搜索这个相同的答案。我最终做的只是弹出obj.pop()所有存储的值/对象在我的对象中,所以我可以重用该对象。不知道这是否是不好的做法。这项技术对于我在Chrome开发工具或FireFox Web控制台中测试我的代码非常方便。

0

将变量设置为null确保打破所有浏览器中对象的引用,包括在DOM元素和Javascript范围之间进行的循环引用。通过使用delete命令,我们标记了要在垃圾收集的下一次运行中清除的对象,但是如果有多个变量引用同一个对象,则删除单个变量将不会释放该对象,它将仅删除该变量之间的链接和对象。在垃圾收集的下一次运行中,只有变量将被清理。

2

刚刚发现一个jsperf你可能会认为这件事很有趣。 (也可能是得心应手,以保持它周围的完成图片)

它比较删除,设置和设置不确定

但请记住,它会测试多次删除/设置属性的情况。

4

delete不用于删除java脚本中的对象。

delete用于你的情况移除object key

var obj = { helloText: "Hello World!" }; 
var foo = obj; 
delete obj; 

对象没有被删除检查OBJ仍然采取相同的价值观删除用法:

delete obj.helloText 

,然后检查obj, foo都是空的目的。

0

这项工作对我来说,虽然它不是一个好的做法。它只是删除该对象所属的相关元素的所有 。

for (element in homeService) { 
      delete homeService[element];