JS数组的浅拷贝和深拷贝

  • Post author:
  • Post category:其他

#背景:

        javascript分原始类型与引用类型。Array是引用类型,直接用  “=” 号赋值的话,只是把原数组的地址(或叫指针)赋值给目标数组,指向的是同一个内存地址,其中一个改变另一个也会改变。并没有实现数组的数据拷贝。这种方式的实现属于浅拷贝。

        深拷贝是开辟新的储存空间,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性

#使用方法:

1.数组浅拷贝

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]

2.数组深拷贝

①JSON.stringfy 和 JSON.parse 方法

var arr1 = [1,2,3,4];
var arr2 = JSON.parse(JSON.stringfy(arr1)) //先将数组转为字符串,然后转为js对象

arr1[0] = 6;
console.log(arr2[0]); //1
console.log(arr1); //[6,2,3,4]
console.log(arr2); //[1,2,3,4]

②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]

③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]

④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]

⑤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]

⑥用for循环遍历复制

var arr1 = [1,2,3,4];
var arr2 = [];
for(i = 0; i < arr1.length; i++) {
  arr2.push(arr[i])
};
arr1[0] = 6;
console.log(arr2[0]); //1
console.log(arr1); //[6,2,3,4]
console.log(arr2); //[1,2,3,4]

        简单来说,深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。

        浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。


版权声明:本文为zyf971020原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。