浅拷贝和深拷贝
Closed this issue · 6 comments
- 浅拷贝: 拷贝的是对象的指针,修改内容互相影响
- 深拷贝: 整个对象拷贝到另一个内存中,修改内容互不影响
arr.slice();
arr.concat();
文中提到这两个方法是浅拷贝,应该是深拷贝的
let arr1 = [1,2,3,4];
let arr2 = arr1.slice(0);
let arr3 = arr1.concat();
arr2[1] =6;
arr3[1] = 6;
console.log(arr1); // [1,2,3,4]
console.log(arr2); // [1,6,3,4]
console.log(arr3); // [1,6,3,4]
let arr1 = [{a: 1},2,3,4]
let arr2 = arr1.slice(0);
arr2[0].a = 2;
自己show一下。
好好想想什么叫做深拷贝
这里你对浅拷贝的理解有些问题哈,你说的浅拷贝是引用类型赋值。
实际浅拷贝是只拷贝引用类型的一层属性,而非你说的赋值。
浅拷贝我举个例子:
const array = [1, 2, 3, 4, [1]];
const cloneArray = array.concat();
console.log(cloneArray); // [ 1, 2, 3, 4, [ 1 ] ]
array.push(5);
// 第一层引用被改变,所以 cloneArray不变
console.log(array); // [ 1, 2, 3, 4, [ 1 ], 5 ]
console.log(cloneArray); // [ 1, 2, 3, 4, [ 1 ] ]
array[4].push(6);
// 只拷贝了一层引用,所以cloneArray index为4的节点也会跟着改变。
console.log(array); // [ 1, 2, 3, 4, [ 1, 6 ], 5 ]
console.log(cloneArray); // [ 1, 2, 3, 4, [ 1, 6 ] ]
另外抱歉这里讲的不好,最近我在完善这里,可以关注下最近更新。
我理解的浅拷贝拷贝的是对象的引用,是个内存地址。而深拷贝则是开辟新内存拷贝,拷贝的是值。
使用 slice()
,concact()
的时候,从上面的例子可以看出,遇到基本类型的时候,进行的是深拷贝。遇到引用类型的时候,进行的是浅拷贝。
但实际上对这个要拷贝的数组而言,拷贝的并不是这个数组的内存地址,而是开辟了新空间进行拷贝,所以我理解成了深拷贝,不知道我这种理解是否有偏差。
- 浅拷贝: 拷贝的是对象的指针,修改内容互相影响
- 深拷贝: 整个对象拷贝到另一个内存中,修改内容互不影响
arr.slice(); arr.concat();文中提到这两个方法是浅拷贝,应该是深拷贝的
let arr1 = [1,2,3,4]; let arr2 = arr1.slice(0); let arr3 = arr1.concat(); arr2[1] =6; arr3[1] = 6; console.log(arr1); // [1,2,3,4] console.log(arr2); // [1,6,3,4] console.log(arr3); // [1,6,3,4]
我感觉你是对slice()和concat()这两个方法的理解有问题,这两个方法返回的都是新数组,所以修改数组中的基本类型数值后和原数组是不一样的。实际上说的浅拷贝是指这两个方法在复制旧数组时用的拷贝方式是浅拷贝。如果数组中元素存在复杂基本类型(如对象),就可以明显看出来了。
我理解的浅拷贝拷贝的是对象的引用,是个内存地址。而深拷贝则是开辟新内存拷贝,拷贝的是值。
使用
slice()
,concact()
的时候,从上面的例子可以看出,遇到基本类型的时候,进行的是深拷贝。遇到引用类型的时候,进行的是浅拷贝。但实际上对这个要拷贝的数组而言,拷贝的并不是这个数组的内存地址,而是开辟了新空间进行拷贝,所以我理解成了深拷贝,不知道我这种理解是否有偏差。
理解的没问题。只不过将slice及concat理解成深拷贝方法,这点有问题。
在前端,浅拷贝,深拷贝,指的数组或对象的复制,与基本类型(字符串,数字,布尔值,null, undefined)无关,基本类型没必要拷贝,基本类型的值的赋值给变量时会直接产生新一份相同的值。
文中指出的拷贝方法,通过这种方法产生出来的新的对象或数组,与传入的参数(数组,或对象,无论其值中是否再存在数组或对象,这就是所谓的嵌套)完全没有关联。因此,这种方法总是可以产生(拷贝)与传入参数完全无关的数组或对象,因此,它是深拷贝方法。
你的举例中,由于arr1([1,2,3,4]),其中的值全部是基本类型,arr1.slice(0),或者arr1.concat()都会返回一个新的数组,产生的数组arr2,与arr3,它们确实与arr没有关联,但是slice,concat并不是深拷贝方法,因为对于数组中值是数组,或对象的,不会复制一份,除了基本类型值,其它的都不会再进行复制。
去查看了下维基百科的定义,发现我之前的理解有误,谢谢楼上各位的指正。
https://en.wikipedia.org/wiki/Object_copying