前两天遇到一个深浅拷贝的问题,浅拷贝并不是我理解的那个浅拷贝,是把浅拷贝和地址引用搞混了,画了个图加深理解
首先来看一段代码;里面包含了浅复制和地址引用;
let arrayA = [1, '这是一个字符串', undefined, null, { obj: '这是一个obj' }];
console.log('原始的arrayA', arrayA)//原始的arrayA [1, 2, 3, 4, 5, 6, 7]
let arrayB = Array.from(arrayA)//浅拷贝(注意,浅拷贝只会拷贝一层)
let arrayC = arrayA//应用arrayA的堆地址
arrayA[0] = 99
arrayA[1] = "修改一下这个字符串"
arrayA[2] = "修改一下这个undefind"
arrayA[3] = "修改一下这个null"
arrayA[4].obj = "修改一下这个obj"
console.log('arrayA', arrayA)//[99, '修改一下这个字符串', 修改一下这个undefind, 修改一下这个null, { obj: '修改一下这个obj' }];
//arrayB是由Array.form浅拷贝来的,
console.log('arrayB', arrayB)//[1, '这是一个字符串', undefined, null, { obj: '修改一下这个obj' }]
//arrayC地址应用(arrayC是指向arrayA这个数组对象的堆内存的内存地址),所以arrayA改变后arrayC也会改变,因为它两指向的是同一个内存地址;
console.log('arrayC', arrayC)//[99, '修改一下这个字符串', 修改一下这个undefind, 修改一下这个null, { obj: '修改一下这个obj' }];
这张图解释了上面那段代码,
首先我们通过字面量定义了arrayA,前四个元素都是基本类型,最后一个元素是一个对象;
然后通过Array.from()浅复制出了一个arrayB;它只会复制一层,这就是所谓的浅复制
Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。(引用自MDN)
arrayB是复制出了一个新的对象,这个数组的前四个元素都是值赋值,所以直接将初始的值复制过来了;arrayB【4】(第五个元素)是Object对象,所以将其地址引用了,通过图也能看到,arrayA和arrayB的第五个元素都指向那个蓝色背景的地址,里面有一个obj;所以在修改了obj后arrayB也对应的变化了。