JS中的数组复制问题
JS中的数组复制问题
前言
首先提到复制,也就是拷贝问题,就必须要明确浅拷贝和深拷贝。
- 浅拷贝:B由A复制而来,改变B的内容,A也改变
- 深拷贝:B由A复制而来,改变B的内容,A的内容不会改变
总的来说就是,基于引用对象的概念,浅拷贝拷贝的是地址,深拷贝直接对值进行了拷贝。
那么在JS的数组中,哪些复制是浅拷贝的?哪些又是深拷贝的呢?这里做一个学习总结。
数组复制
直接赋值符号 “=” 复制
let arr1 = [2,3,4,5,6];
let arr2 = arr1;
arr2.push(12);
console.log(arr1); //[2, 3, 4, 5, 6, 12]
console.log(arr2); //[2, 3, 4, 5, 6, 12]
可以看到通过赋值符号 “=” 复制是浅拷贝。
扩展
数组属于引用数据类型,那么我们可以猜测,通过 赋值符号 “=” 赋值的引用数据类型的变量的复制都是浅拷贝,验证如下:
let obj1 = {value:23};
let obj2 = obj1;
obj2.value = 12;
console.log(obj1); //{value: 12}
console.log(obj2); //{value: 12}
那么值(基础)数据类型呢?
let num1 = 23;
let num2 = num1;
num2 = 12;
console.log(num1); //23
console.log(num2); //12
可以看到 基础数据类型通过赋值符号 “=” 的复制是深拷贝的,但要注意,如果你通过对象的方式进行定义的话,那么基础数据类型也会变成对象,对象的直接复制仅仅只复制了地址。
let num1 = new Number(23);
let num2 = num1;
num2 = 12;
console.log(num1); //23
console.log(num2); //12
数组中的复制函数
我们知道,js提供了很多数组复制的方法,例如拆分操作符(...),map函数,concat函数,slice函数,这些方法都可以进行数组的复制,那么今天就一起总结下哪些复制是浅拷贝的,哪些是深拷贝的。
let arr1 = [2,3,4,5,6];
arr2 = [...arr1];
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]
可以看到通过拆分操作符进行的复制是深拷贝的,arr2指向的是一个新的地址
let arr1 = [2,3,4,5,6];
arr2 = arr1.map(item=>item);
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]
let arr1 = [2,3,4,5,6];
arr2 = arr1.concat();
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]
let arr1 = [2,3,4,5,6];
arr2 = arr1.slice();
arr2.shift();
console.log(arr1); //[2, 3, 4, 5, 6]
console.log(arr2); //[3, 4, 5, 6]
经过验证,拆分操作符(...),map函数,concat函数,slice函数的复制均为深拷贝。