javascript对象中的浅拷贝问题

const girl = {

  name: 'Anna',

  info: { age: 20, number: 123 }

};


const newGirl = { ...girl };

newGirl.info.age = 30;

console.log(girl.info.age, newGirl.info.age);

输出为 30 30,我们使用展开运算符将 girl 对象的属性复制到 newGirl 对象中。此运算符创建对象的浅表副本。浅拷贝不能避免突变。


让我们看另一个例子


function test(obj) {

  const output = { ...obj };

  output.age = 30;

  return output;

}


let person = { age: 10 }

let newPerson = test(person);

console.log(newPerson.age, person.age); // output is 30 10

如您所见,第二个示例也使用展开运算符来创建对象的副本。为什么它的行为与第一个示例不同?为什么它不影响原始对象字段数据?



慕尼黑8549860
浏览 190回答 3
3回答

千万里不及你

不同之处在于,在第一个代码段中,您修改了属性中的嵌套对象info,而在第二个代码段中,您修改了包含对象。当您进行浅拷贝时,girl和newGirl是不同的对象,但它们都包含对同一info对象的引用。Sogirl.info和newGirl.info是同一个对象,修改其中一个的属性会通过访问另一个反映出来。但是,如果您分配给girl.name或newGirl.name正在修改不同对象的属性。您不会看到其他对象的变化。这就是您在第二个代码段中通过分配给所做的事情output.age。深拷贝会复制递归引用的所有对象,而不仅仅是顶级对象。如果您进行深拷贝,则在访问其他对象时不会看到任何级别的修改。

料青山看我应如是

中唯一的值person是不可变的原语 ( 10)。没有可以通过引用复制的对象(与对象girlwhere不同)。info

呼如林

您在第二个示例中更改了两件事:将对象传入和传出函数改变了对象的结构您看到的差异与通过函数的额外间接无关,仅与对象的结构有关。让我们一次改变一件事,看看会发生什么:const girl = { age: 20, number: 123 };const newGirl = { ...girl };newGirl.age = 30;console.log(girl.age, newGirl.age);输出:20 30- 原始对象没有被修改,因为我们直接复制了标量值age,所以这两个属性是完全分开的。function test(obj) {  const output = { ...obj };  output.info.age = 30;  return output;}let person = { info: { age: 10 } }let newPerson = test(person);console.log(newPerson.info.age, person.info.age);输出是30 30- 原始对象已被修改,因为我们只复制了属性的对象引用info,所以两个属性都持有指向同一个对象的引用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript