2010-07-15 75 views
1

我不是很肯定的問題標題, 這裏的情況,請參見下面的示例代碼JavaScript對象的屬性值衝突

// original data 
a = [ 
    {x : 1}, 
    {x : 2}, 
    {x : 3} 
] 

// assign to a variable 
b = a[0] 

// do some change 
b.x = 5 

alert(a[0].x) 
// i thought it would still be 1 but it is 5, why??? 

*編輯
謝謝琥珀和安德烈
我認爲我只寫一個函數來循環通過對象屬性來複制到一個新的對象
再次感謝您的幫助:)

+0

你應該看看http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object關於如何做到這一點的一些建議。 – 2010-07-15 08:13:17

回答

1

對象通過引用分配 - 這意味着當您修改任何東西t引用這個對象,它會在每一個被引用的地方修改它。

b僅存儲到同一個對象,該對象被a[0]存儲到基準的基準。

+0

有什麼辦法可以避免這種情況發生? 或每次我想修改一個對象屬性,我必須將它存儲到另一個變量? – ben 2010-07-15 07:17:16

+0

那麼如果我需要將存儲在另一個obj中的數據複製到另一個obj而不參考? – ben 2010-07-15 07:22:51

+0

你必須做所謂的'深拷貝' - http://snipplr.com/view/15407/deep-copy-an-array-or-object/ – Amber 2010-07-15 17:42:33

0

想想這樣。 a[0]不是實際的物體{x : 1}。該對象位於內存中,a[0]保存該對象存儲的內存地址。

如果你這樣做,你a[0].x它解引用。這意味着您需要分析.之前的部分並查看地址。然後,您可以在該地址處獲取對象並查看它是否有一個屬性x並將其返回。

但是,如果你b=a[0]你基本上只是複製對象的地址到b中。所以現在你有兩個引用(對象被存儲的內存地址的快捷方式)。如果你現在做b.x = 5你看看之前的.;這是b包含對象的地址,你從內存中取該對象,檢查它是否具有財產x,並在同一地址(因此在相同的對象),它的值更改爲5。但是a[0]點,所以如果你嘗試做a[0].x像以前一樣,你到達你剛剛修改的地址。

這是一個有點簡單的解釋,但你應該想到的控股對象作爲快捷方式到實際對象的內存地址的變量。如果您嘗試將變量分配給另一個對象變量的值,您只需創建一個新的快捷方式。對於包含數字的變量,這不是真的,所以x實際上保留值15,而不是地址。所以如果你這樣做:

y = a[0].x; 
y = 10; 

a[0].x不會改變它的價值。

+0

謝謝安德烈:)我想這意味着我不能只是複製一個對象節點的樹到另一個對象,我將不得不分配值一個一個:( – ben 2010-07-15 07:25:38