2016-05-25 48 views
1

我在http://jsbin.com/givolafala/edit?html,js,console,output「Object.assign」在更深的層次

var oldObject = { name: 'John', address: { city: 'new york'}}; 
 

 
var newObject = Object.assign({}, oldObject); 
 

 
console.log(oldObject); 
 
console.log(newObject); 
 

 
newObject.name = 'Mathew'; 
 
newObject.address.city = 'los angeles'; 
 

 
console.log(oldObject); 
 
console.log(newObject);

具有樣品JSBin代碼在這個例子中變異狀態,我改變名稱其是在頂級從JohnMathewObject.assign以新名稱Mathew返回新狀態。 oldObject保持其以前的值John

如果我更改任何其他級別的任何值,而不是根,它不起作用。在示例中,我將城市更改爲los angeles,並且您會注意到newObjectoldObject具有相同的城市los angeles。所以oldObject狀態是變異的。

這是一個錯誤?

+0

如果你想遞歸Object.assign簽出[deep-assign](https://www.npmjs.com/package/deep-assign) –

回答

3

這不是一個錯誤,這叫做參考。原始值和對象(實際引用對象)的行爲之間存在差異。

var oldObject = { name: 'John', address: { city: 'new york'}}; 

oldObject包括:

  • name它是一個字符串(原始)
  • addres這是一個對象,所以oldObject真的有參考address對象

現在:

var newObject = Object.assign({}, oldObject); 

複製newObject後也有name價值address參考

newObject.name = 'Mathew'; 

這裏你改變newObject的屬性值。

newObject.address.city = 'los angeles'; 

但在這裏你改變一個對象的屬性,newObject引用。但是這個參考也在oldObject,所以這也會改變oldObject

基本上既newObjectoldObject具有參照相同相同address對象

你期望達到的是深拷貝

2

我想的Object.assign()描述說的一切:

Object.assign()從源對象到目標對象方法僅複製枚舉和自己的屬性。
它使用源上的[[Get]]和目標上的[[Set]],因此它會調用獲取器和設置器

因此,它分配屬性而不僅僅是複製或定義新屬性。如果合併源包含getter,這可能會使它不適合將新屬性合併到原型中。爲了將屬性定義(包括它們的可枚舉性)複製到原型中,應該使用Object.getOwnPropertyDescriptor()Object.defineProperty()