2017-05-31 64 views
3

當兩個數組中存在相同的對象引用時,這些對象是等效的,並且更新一個會影響另一個。js從兩個數組中刪除對象引用

但是從一個陣列刪除對象中的其他不刪除它。

爲什麼不呢?

var a1 = [ 
    {i: 0, s: 'zero'}, 
    {i: 1, s: 'one'} 
]; 

var a2 = [ 
    a1[0], 
    a1[1] 
]; 

// items point to same reference 
print(a1[0] === a2[0]); // true (equivalent) 

// updating one affects both 
a1[0].s += ' updated'; 
print(a1[0] === a2[0]); // true (still equivalent) 
print(a1[0]); // {"i":0,"s":"zero updated"} 
print(a2[0]); // {"i":0,"s":"zero updated"} 

// however, deleting one does not affect the other 
delete a1[0]; 
print(a1[0]); // undefined 
print(a2[0]); // {"i": 0, "s": "zero"} 

有趣的是,從一個屬性中刪除一個屬性,確實會影響到其他屬性。

delete a1[1].s; 
print(a1[1]); // {"i":1} 
print(a2[1]); // {"i":1} 

https://jsfiddle.net/kevincollins/4j6hj2v7/3/

+13

您刪除對該值的引用,而不是該值本身。看到它就像給一個人分配一個名字一樣。如果你不再叫他們克里斯,他們不會突然消失。 – Halcyon

+2

對象使用引用進行分配。所以當你執行'a1 [0]'時,它將獲取其引用並將其複製到數組中,並將用它來訪問值。所以當你刪除引用時,你刪除了原始位置,因此它會反映在所有變量中。 – Rajesh

+0

不要在數組中使用'delete'。只需將索引設置爲「null」或「undefined」。 – Bergi

回答

1

要回答爲什麼最後print(a2[0]);仍顯示值,讓我們開始分析代碼。

a1是一個數組,當你使用對象初始化,它會創建對象和存儲他們參考。

var a1 = [ 
    {i: 0, s: 'zero'}, // ref 1001 
    {i: 1, s: 'one'} // ref 1002 
]; 

這部分,你的意見是明確的,但是當你做delete a1[0]會發生什麼?

將它刪除對象?答案是否。它將刪除a10索引處存儲的財產,並將其設置爲undefined。但是,如果你在刪除該引用舉行的對象的屬性,它會顯示兩個:sample

會發生什麼對象呢?價值被保留,並將被垃圾收集,如果沒有人引用它。在你的情況下,由於a2[0]仍在訪問它,它將保留該值。

您可以檢查以下sample以供參考。

0

像@Halcyon說,要刪除的參考,而不是對象本身。爲了演示,看看下面的例子:

var a = 2 
var b = [a, 2, 3, 4] 

如果你要delete b[0],你只會刪除提及,因此,a===2。但是,如果你要刪除的a參考,通過delete a,然後在b值將改爲undefined,因爲在該位置存在所使用的參考,而現在沒有

+1

這就是我所期待的。但是在這個例子中,'a'不會被刪除。 https://jsfiddle.net/kevincollins/f30euchx/ –

+1

@KevinCollins重要的是要記住,文字(數字,字符串等)不能被刪除,如果你引用一個,你不能'刪除'它 – MayorMonty