一、名称来源
浅拷贝(Shallow Copy) :
-
“浅” 这个词形象地说明了这种拷贝方式只复制了对象的 “表面” 部分。它仅复制了对象的第一层属性,如果属性是基本数据类型,那么这些值会被复制;但如果属性是引用类型(如对象或数组),它只会复制引用,而不会深入到引用类型内部去复制其实际内容。就好像只是在表面上做了一个简单的复制,而没有深入到对象的内部结构。
深拷贝(Deep Copy) :
-
与浅拷贝相对,“深” 表示拷贝的深度更深。它会递归地复制对象的所有层级,不仅仅是第一层。它会深入到对象内部,对于对象内部的嵌套对象、数组等引用类型,也会创建新的副本,确保新对象和原对象及其嵌套对象完全独立,不会共享任何引用,就像对对象进行了深度的复制操作。
二、类比解释
浅拷贝:
-
可以把对象想象成一个房子,浅拷贝就像是复制了房子的地址和钥匙。你可以使用新的钥匙进入房子,但房子里的家具(引用类型)还是原来的那些,如果你改变了房子里的家具,原房子和新复制的房子里的家具都会发生改变,因为它们指向的是同一套家具。
深拷贝:
-
深拷贝则像是重新盖了一栋一模一样的房子,并且里面的家具也是全新复制的。新的房子和原来的房子完全独立,无论你对其中一栋房子里的家具做什么操作,都不会影响另一栋房子里的家具。
三、实际影响
浅拷贝:
-
在浅拷贝中,由于引用类型没有被真正复制,只是复制了它们的引用,所以修改浅拷贝对象的引用类型属性会影响原对象,因为它们指向的是相同的内存地址。
收起
javascript
let original = { name: 'Alice', hobbies: ['reading','swimming'] };
let shallowCopy = {...original };
shallowCopy.hobbies.push('painting');
console.log(original.hobbies); // ['reading','swimming', 'painting']
深拷贝:
-
深拷贝创建了一个完全独立的对象,对深拷贝对象的修改不会影响原对象,因为它递归地复制了所有引用类型的内部结构。
收起
javascript
let original = { name: 'Alice', hobbies: ['reading','swimming'] };
let deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.hobbies.push('painting');
console.log(original.hobbies); // ['reading','swimming']
四、使用场景
浅拷贝:
-
当你只需要复制对象的第一层,并且不关心对引用类型属性的修改是否会影响原对象时,可以使用浅拷贝。例如,复制一个对象,仅修改其基本数据类型的属性,而不涉及引用类型属性的修改。
深拷贝:
-
当你需要完全独立的对象副本,尤其是涉及对对象内部嵌套结构的修改时,使用深拷贝。例如,复制一个配置对象,需要对其内部的对象或数组进行修改,但不希望影响原对象。
五、总结
- 浅拷贝和深拷贝的名称是根据它们复制对象的深度来命名的,它们在复制的彻底性上有所不同,在不同的开发场景中有着不同的用途。