包含对象的数组中的浅拷贝与深拷贝

时间:2020-11-11 08:10:35

标签: javascript ecmascript-6

浅复制只不过是在尝试复制和更改复制的数组{包含对象而不是原始数据类型的数组}的内容时,原始数组的内容也发生了更改。

在以下情况下,为什么dst [0] = {name:“ tom”}是深层副本而不是浅层副本(原始数组“ src”的内容未更改)。相反,第二个操作dst [0] .name =“ tom”正在按预期方式创建浅表副本并更改src的内容。有人可以澄清一下吗?

let src = [{
  name: 'brat'
}, {
  age: 40
}]
let dst = [...src]


// dst[0]={name:"tom"} 
dst[0].name = "tom";


console.log(`src ${JSON.stringify(src)}`)
console.log(`dst ${JSON.stringify(dst)}`)

2 个答案:

答案 0 :(得分:2)

这是因为在下面的行中,您没有更改src的复制属性,而是重新分配了“键”和“值”,并将旧属性完全替换为新属性。

dst[0]={name:"tom"} 

与此相同:

dst[0]={newName:"tom"} 

它被视为dst的新属性,而不是从src复制的属性,这就是原始对象不变的原因,因为此“ name”属性与从原始对象复制的属性不同。

当您使用{name:“ tom”}将值重​​新分配给dst时,将从堆中释放 dst [0] 的内存,并用新的对象替换 dst [0] ,它不是从 src [0] 浅拷贝的对象。

答案 1 :(得分:1)

dst[0]={name:"tom"}dst[0].name = "tom";不是副本,它们只是作业。一个更改dst数组(将一个新对象设置为第一个元素),另一个更改第一个对象(为.name属性设置一个新的字符串)。

浅表副本发生在let dst = [...src]行中,如果您不进行更改,它总是浅表副本,其中dst包含与{{ 1}}。