js对象的深度拷贝/复制和浅度拷贝/复制 方法
概念:
深度拷贝与浅度拷贝的区别主要是在于有没有为拷贝出的新对象在堆中重新分配一块内存区域。
浅度拷贝即直接赋值, 拷贝的只是原始对象的引用地址,在堆中仍然共用一块内存。所以当复制品变化了,原对象也会改变。
arr1=arr2,则arr2被复制了一个引用地址,它俩共用一个内存。
深度拷贝为新对象在堆中重新分配一块内存,所以对新对象的操作不会影响原始对象。
什么情况下要进行深度拷贝?
我们在复制一个对象的时候,对它进行操作,为了不让新对象影响到原始对象,要对它进行深度拷贝。
数组和对象等引用类型的数据都可以进行深度拷贝。
1. 以对象数组为例-比较浅度拷贝和深度拷贝的区别
复制一个arr1数组,为arr2. 并为arr2添加一个新的属性count.
浅度拷贝
// 浅度复制
var arr1=[
{
id:1,name:'xiaoming',age:16},
{
id:2,name:"xiaobai",age:19}
]
var arr2=[]
function copyarr1(arr){
for (var i = 0; i < arr.length; i++) {
var obj1=arr[i] //obj1直接复制对象名
obj1["count"]=0 //给arr2的obj添加新属性
console.log(obj1)
arr2.push(obj1)
}
}
copyarr1(arr1)
console.log("--arr2---")
console.log(arr2)
console.log("--arr1---")
console.log(arr1)
浅度复制解析
可以看到,为arr2的对象添加了属性count, 原arr1的对象也被添加上了属性。
当arr2复制arr1时,定义的obj1直接让arr1[ i ]赋的值,此时由于arr的子对象arr1[ i ]为引用类型的数据obj.
引用数据类型:名 存在栈内存中,值 存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值.
所以说,obj1实际上只是复制了一个引用地址,并没有把arr1[i]的值复制一遍,obj1和arr1[i] 是两个指针,共用一个值。
而当我们对obj1进行增删改的时候,由于obj1与arr1[i]指向的是同一个值,它俩共用的值变了,所以arr1 [i]指针指向的对象已经变了。
除此之外,因为共用一个值,浅度复制还产生一些其他的影响。
浅度复制在给对象数组添加新字段时的影响
以购物车需求为例:
for (var i = 0; i < state.cartlist.length