前言
这里涉及到一点内存知识 详情小知识;
浅拷贝和深拷贝
请看代码
var res = [12,12,234];
var arr = res;
res[0] = 'Hello World'
console.log(arr);
以上代码正常来看 arr应该会输出 [12,12,234] 因为 改变的是 res[0] 的元素值
和arr无关 但是
此时的arr的值却被改变了
这种情况就是浅拷贝
改变父元素的值 却改变了 被赋值元素的值
var res = '1212234';
var arr = res;
res = 'Hello World'
console.log(arr);
此时arr的值仍然是正常的1212234 ;
此时就是深拷贝
小结
一般来说 基本数据类型 都不会发生浅拷贝 ,一般来说发生深拷贝的 都是 引用数据类型 具体点来说 是变量值的指针都指向堆内的同一个数组 见下图解↓
深拷贝的实现方式
//最容易明白的方式 遍历push进去
var arr = [1,2,3,4,5,6,7,8,9,0,9,8,7,6,6,5,4,3,2,1]
var res = []
for(var i = 0;i < arr.length;i++){
res.push(arr[i])
}
console.log(res);
//
res = [...arr]; //最简单的方式
var CCC = [
{name:'张三',
age: 18,
dec:[1,6,4,3,2,6,8,6]
},
{name:'李四',
age: 25,
dec:[1,6,5,2,2,8,3,6]
},
{name:'王二麻子',
age: 114514,
dec:['哼','哼','啊啊啊啊',3,2,6,8,6]
}
]
//做递归深拷贝 万金油 缺点:效率较低
deepCopy(CCC);
function deepCopy(params){
//数组处理
if(Array.isArray(params)){
var res = []
for(var i=0;i<params.length;i++){ //遍历数组
if(params[i] instanceof Object){ //
// 在遍历数组的时候判断遍历的是否是对象 如果遍历到对象 那么把对象传给自己拷贝
res.push(deepCopy(params[i]))
这边push接受 拷贝对象之后的对象
}else{
// 否则就正常元素push
res.push(params[i])
}
}
return res //返回一个拷贝之后的值
}
//对象处理
if(params.constructor === Object){ //判断是否是对象
var res = {}
for(var x in params){ //遍历对象
if(params[x] instanceof Object){ //如果遇到是一个对象
res[x] =deepCopy(params[x])
// 这里把自己当作工具人去把遇到的对象深拷贝一下
}else{
res[x] = params[x] //否则正常拷贝
}
}
return res //返回一个拷贝之后的值
}
}