浅复制只不过是在尝试复制和更改复制的数组{包含对象而不是原始数据类型的数组}的内容时,原始数组的内容也发生了更改。
在以下情况下,为什么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)}`)
答案 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}}。