总结一下深复制和浅复制的区别,以及实现他们的方法。
浅复制和深复制的区别
对于基本类型(Undefined、Null、Boolean、Number 和 String),浅复制是对值的复制,对于引用类型来说,浅复制是对地址的复制,那么对于地址的复制又是什么意思呢?一段代码解释一下:
let arr1 = [1, 2, 3] |
而深复制则是开辟新的栈,两个属性对应两个不同的地址,修改一个属性的数据,不会改变另一个属性数据。
浅复制
let obj = { a:1, arr: [2,3] }; |
原因:因为浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shallowObj.arr 指向同一块内存地址。
深复制
1. JSON实现
b = JSON.parse(JSON.stringify(a)) |
这个方法最方便,但是有它的局限性。
- 无法复制函数
- 原型链没了,对象就是 object,所属的类没了。
那么为什么不能复制函数呢?因为:JSON.stringify 函数将一个 JavaScript 对象转换成文本化的 JSON。不能被文本化的属性会被忽略。所以函数就被忽略调了。
2. 递归实现
// 递归深拷贝! |
实现的原理
实现原理,先新建一个空对象,内存中新开辟一块地址,把被复制对象的所有可枚举的(注意可枚举的对象) 属性方法一一复制过来,注意要用递归(如果传入的变量是一个数组或者对象,那么就进行递归)来复制子对象里面的所有属性和方法,直到子子…..属性为基本数据类型。
总结,深拷贝需要理解两点:
- 新开辟内存地址
- 递归来刨根复制