'Object.assign'在更深层次上改变状态

won*_*rld 2 javascript javascript-objects ecmascript-6

我在http://jsbin.com/givolafala/edit?html,js,console,output中有一个示例JSBin代码

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);
Run Code Online (Sandbox Code Playgroud)

在此示例中,我将顶级名称John更改为Mathew。将Object.assign返回一个具有新名称的新状态Mathew。在oldObject保留其先前的值John

如果我更改了除根目录以外的任何级别的任何值,则它将不起作用。在示例中,我将城市更改为los angeles,您会注意到newObject和和oldObject具有相同的城市los angeles。因此oldObject状态是突变的。

这是错误吗?

Jak*_*zak 5

这不是错误,称为参考。原始值和对象(实际上是对对象的引用)的行为方式有所不同。

var oldObject = { name: 'John', address: { city: 'new york'}};
Run Code Online (Sandbox Code Playgroud)

oldObject 包括:

  • name这是一个字符串(原始)
  • addres这是一个对象,所以oldObject确实具有参考address对象

现在:

var newObject = Object.assign({}, oldObject);
Run Code Online (Sandbox Code Playgroud)

复制后newObject也具有name 价值address 参考

newObject.name = 'Mathew';
Run Code Online (Sandbox Code Playgroud)

在这里,您更改newObject的属性值。

newObject.address.city = 'los angeles';
Run Code Online (Sandbox Code Playgroud)

但是在这里,您可以更改newObject 引用的对象的属性。但是这个参考也存在,oldObject所以它也会改变oldObject

基本上都newObjectoldObject具有到相同相同的参考address对象

您期望实现的目标称为深度复制