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函数的复制均为深拷贝。

上一篇:[转]在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView


下一篇:python之正则表达式备忘