浅拷贝
js中,引用类型数据存储的是地址值,浅拷贝拷贝的是地址值,常见的如简单“=”赋值
示例
let arr1=[1,2,3];
arr2=arr1; //将arr的地址值赋给arr2,此时arr1和arr2共享一块连续的地址
arr2[1]=0; //将arr2[1]赋为0,会影响到arr1[1]的值,因为两者对应的内存地址一致
console.log(arr1[1]); //0
2.fill()函数填充
对象
let obj={
name:"小张",
age:19
};
let objs=new Array(3).fill(obj); //为数组的每个元素赋值为odj(一个地址值)
objs[1].name="小李"; //修改objs[1].name的值,obj.name的值也会改变。
console.log(obj); //{name: '小李', age: 19}
数组
let arr1=new Array(3).fill(new Array(4).fill(0));
/*
以这种方式定义的二维数组,其实相当于一维,
分析:首先 new Array(4).fill(0) 创建了一个大小为4的元素都为0的数组 且记为t
new Array(3).fill(new Array(4).fill(0)) 创建一个大小为3的,每个元素值为t(t[0]的地址)的数组,即3*4的二维数组
*/
arr1[1][2]=4;
//改变arr1[1][2]的值,由于arr1的每个元素的值都一样(都为t[0]的地址),所以 arr[0][2],arr[1][4],arr[2][4]都被赋为4
arr1.forEach(it=>{console.log(it[2]+" ")}); // 4 4 4
深拷贝
深拷贝拷贝的是数据值,拷贝出来的是原数据的副本
常见的数组深拷贝操作
1.slice(i)
参数i表示原数组的起始地址偏移量,默认为0
let arr1=[1,2,3];
let arr2=arr1.slice(1); //从arr1的下标1开始往后复制
let arr3=arr1.slice(); //默认从arr1的下标0开始往后复制,即复制整个数组
arr2.forEach(it=>{console.log(it+" ")}); //2 3
arr3.forEach(it=>{console.log(it+" ")}); //1 2 3
2.concat(…i)
可接受多个参数,表示要附加到数组末尾的元素,默认不添加元素
let arr1=[1,2,3];
let t1=[2,3,4]; let t2=[4,2,6];
let arr2=arr1.concat(); //将arr1复制给arr2
let arr3=arr1.concat(2,3); //arr1后加2和s的结果复制给arr2,注:arr的内容不变
let arr4=arr1.concat(t1,t2); //arr1后加t1数组和t2数组的结果复制给arr2,注:arr的内容不变
arr2.forEach(it=>{console.log(it+" ")}); //1 2 3
arr3.forEach(it=>{console.log(it+" ")}); //1 2 3 2 3
arr4.forEach(it=>{console.log(it+" ")}); //1 2 3 2 3 4 4 2 6
3.ES6扩展运算符
let arr1=[1,2,3];
let arr2=[...arr1]; //将arr1扩展为1,2,3复制给arr2 也可接多个数组值,如arr2=[...arr1,...t1,...t2]多个值用“,”隔开
let [...arr3]=arr1; //另一种写法
arr2.forEach(it=>{console.log(it+" ")}); //1 2 3
arr3.forEach(it=>{console.log(it+" ")}); //1 2 3
对象的深拷贝
1.先转json格式,再转对象
let obj1={
name:"张三",
sex:"男",
age:20
};
let obj2=JSON.parse(JSON.stringify(obj1));
console.log(obj2); //{name: '张三', sex: '男', age: '20'}
2.ES6扩展运算符
let obj1={
name:"张三",
sex:"男",
age:20
};
let obj2={...obj1}; //将obj1扩展为 name: '张三', sex: '男', age: '20'
console.log(obj2); //{name: '张三', sex: '男', age: '20'}
注ES6扩展运算符还可实现灵活复制
let obj3={
sum:50, //自定义属性
...obj1, //将obj1扩展为各个属性
...obj2 //将obj2扩展为各个属性
};