js 数组的浅拷贝和深拷贝
小明明同学 人气:01.背景介绍
javascript分原始类型与引用类型。Array是引用类型,直接用“=”号赋值的话,只是把源数组的地址(或叫指针)赋值给目的数组,指向的是同一个内存地址,其中一个改变另一个也会改变。并没有实现数组的数据的拷贝。这种方式的实现属于浅拷贝。
深拷贝是开辟新的储存空间,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。
2.使用方法
数组浅拷贝:
var arr1 = [1, 2, 3, 4]; var arr2 = arr1; arr1[0] = 6; //数组是用堆去保存的,相等的时候只是把存放的地址拷贝过去了,两个指向了同一个地址,所以在改变其中一个的值,其他的也跟着改变了 console.log(arr2[0]); //输出结果为6 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[6, 2, 3, 4]
数组深拷贝:
1.JSON.stringify和JSON.parse方法
var arr1 = [1, 2, 3, 4];
var arr2 = JSON.parse(JSON.stringify(arr1)) //先将数组转为字符串,然后转成js对象
arr1[0] = 6; console.log(arr2[0]); //输出结果为1 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[1, 2, 3, 4]
2.slice方法
var arr1 = [1, 2, 3, 4]; var arr2 = arr1.slice(0); //从0开始到末尾截取数组,然后返回一个新的数组 arr1[0] = 6; console.log(arr2[0]); //输出结果为1 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[1, 2, 3, 4]
3.concat方法
var arr1 = [1, 2, 3, 4]; var arr2 = arr1.concat(); //连接数组,如果连接的是一个空,那么也是返回了新的本身的数组 arr1[0] = 6; console.log(arr2[0]); //输出结果为1 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[1, 2, 3, 4]
4.map方法
var arr1 = [1, 2, 3, 4]; var arr2 = arr1.map(function(value){ return value; }) //使用map方法遍历数组然后返回新的数组,里面的值不变 arr1[0] = 6; console.log(arr2[0]) //输出结果为1 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[1, 2, 3, 4]
5.ES6语法
var arr1 = [1, 2, 3, 4]; var [ ...arr2 ] = arr1; //ES6扩展运算符实现数组的深拷贝 arr1[0] = 6; console.log(arr2[0]); //输出结果为1 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[1, 2, 3, 4]
6.用for循环遍历复制
var arr1 = [1, 2, 3, 4];
var arr2 = [];
for(i=0;i<arr1.length;i++){
arr2.push(arr1[i])
}
arr1[0] = 6; console.log(arr2[0]); //输出结果为1 console.log(arr1); //[6, 2, 3, 4] console.log(arr2); //[1, 2, 3, 4]
简单来说,深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。
浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。
那具体使用情况该使用浅拷贝还是深拷贝呢,没有一成不变的规则,一切都取决于具体需求~
加载全部内容