Wenn ein Referenztyp einem anderen Referenztyp zugewiesen wird, verweisen diese nur auf dieselbe Adresse und die Vorgänge beeinflussen sich gegenseitig.
Bei der Tiefenkopie wird Speicherplatz neu zugewiesen, sodass er und das vorherige Objekt oder Array nicht beeinträchtigt werden.
Flache Kopie entspricht der Zuweisung des Referenztyps.
var a={banner:{size:1,weight:'0.5kg'}};
var b={apple:{size:1},banner:{size:3}};
$.extend(true,a,b)=>{banner:{size:3,weight:'0.5kg'},apple:{size:1}};
$.extend(a,b)=>{banner:{size:3},apple:{size:1}};
Ich habe gesehen, dass der JQuery-Quellcode eine Rekursion erfordert.
Aber ich verstehe nicht, was das mit gegenseitiger Beeinflussung zu tun hat, oder ist mein Verständnis des oben genannten Konzepts falsch
浅拷贝
仅对object顶层键进行遍历和重新赋值(给对应的引用),例如:
这个过程里面,从b中取出所有顶层元素,即b.x, b.y, b.z,然后将它们一一赋值给a对应的键,所以最后a就有了新的a.x, a.y, a.z,同时,a.o还保留在a中,这时a.x === b.x, a.y === b.y, a.z === b.z,因为它们都是指向同一个对象的引用。既然是引用,当你操作a.x的时候,比如a.x.name = 'x3',那么b.x.name也就变成了'x3'。
深拷贝
深拷贝将深入对象元素的末层进行重新赋值,而非引用。就拿上面的a,b举例,执行:
将会深入b内部进行遍历,拿每一个节点的值与a对应(一模一样)的节点进行比较,如果不同则为a开辟存储空间,把值赋进去,如果a不存在这个节点,就为它创建后赋值进去。a的第一层子节点跟b第一层不存在相等关系,连==都不成立。
深拷贝后,a原有的一些节点会保留下来,b给过去的节点会覆盖或增加,但是和b之间不存在任何引用关系,所以修改a的任何一个节点,都不会影响b。这在一些数据处理的时候非常有用,为了不影响原始数据,需要在处理数据之前深拷贝一份再进行处理。
深拷贝的时候,数组的索引号被当做键名对待,所以数组元素会被修改,而不是被添加到原始数据中。比如:
将会得到:
b的第一个原始被合并到a的第一个元素里面去了,这个合并是因为数组按照元素的索引号作为键来进行操作。所以,合并数组不能用extend,而应该考虑用merge或concat。
只是名字重复了,和深拷贝/浅拷贝没有关系。应该叫递归拷贝比较合适。