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];