2010-07-15 73 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