JS如何实现多层对象或数组的深拷贝
在js中我们时常要实现数据的克隆,也是我们这里所要谈到到的拷贝。数据的拷贝分为浅拷贝和深拷贝。
浅拷贝:拷贝的只是在对中存放的对象或者数组的指针,对拷贝后的数据进行修改时原数据也会自动进行修改。
深拷贝:会在堆中重新开辟一个空间,将数据复制进去,形成一个新的地址。
注:基本类型数据存放在栈当中,所进行的拷贝都为深拷贝。引用类型数据存放在堆中,不能直接进行复制拷贝,直接赋值拷贝的只能为指针。
浅拷贝
var arr = [1,2,3,4];
var copyArr = arr; // 直接对数组进行赋值
copyArr.push('new content');
arr.push('old');
console.log(copyArr,arr); // 打印的结果如下
可以看到,新数组在push进’old’后,原数组的长度也增加了;这是因为数组在进行赋值时,所赋值的为原数组的指针,新的变量访问该指针还指向原来的数据位置。
深拷贝
实现对单层数组与对象的深拷贝
// 数组
// 方式一
var copyArr1 = []
for(var i = 0 ;i<arr1.length;i++){
copyArr1.push(arr1[i])
}
// 方式二
var copyArr1 = [...arr1] // 使用展开运算符
// 对象
// 方式一
var copyObj1 = {}
for(var x in obj){
copyObj1[X] = obj[x]
}
// 方式二
var copyObj1 = {...obj}
在深拷贝数组或者对象时,可以使用push方法或者直接使用展开运算符,但这只能拷贝单层数组或者对象;对于数组里面再嵌套数组或对象的数据,依旧使用这种方法时所拷贝的内层数据只能拷贝该数据的指针,所以得使用另一种方法。
实现对多层数组与对象的深拷贝
// 方式一 使用递归深拷贝
// 在这里封装了一个方法,使其可以实现多层数组或对象的深拷贝
function deepCopy(params) {
// 如果是数组
if (Array.isArray(params)) {
var res = [];
for (var i = 0; i < params.length; i++) {
if (params[i] instanceof Object) {
// 将深层拷贝的结果的 添加到 res 中
res.push(deepCopy(params[i]));
} else {
res.push(params[i]);
}
}
return res;
}
// 如果是对象 进行 对象的拷贝
if (params.constructor === Object) {
var res = {}; // 1 声明空对象
for (var x in params) {
// 遍历被拷贝对象
// 如果你是数组或者对象;需要再次拷贝
if (params[x] instanceof Object) {
// 将深层拷贝的结添加到 res中
res[x] = deepCopy(params[x]);
} else {
// params[x] 为基本类型数据 直接添加大res中
res[x] = params[x];
}
}
return res
}
}
// 方式二 使用JSON方法
var data = [{
name:'ya',
list:[
{name:'dddd'}
]
}]
var dataStr = JSON.stringify(data); // JSON.stringify 将数据或者对象,变为 json 字符串 并【返回字符串】
var res = JSON.parse(dataStr); // JSON.parse() 将json 字符串转化为 数组或者对象;并【返回】数组或者对象
console.log(res);