当前位置: 代码迷 >> 综合 >> JavaScript中如何使用递归完成对对象的深拷贝
  详细解决方案

JavaScript中如何使用递归完成对对象的深拷贝

热度:24   发布时间:2023-10-26 07:01:52.0

先上代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>obj = {a : 1,b : 2,c : 3,d : {e : 4},f : [1,2,3]}function deepcopy(obj) {// 如果obj是数组,返回数组的深拷贝if (Array.isArray(obj)){// 巧妙利用slice()方法完成深拷贝return obj.slice()// 利用toString()方法判断obj是否为对象}else if (obj.toString() === '[object Object]'){// 将对象转化为二维数组var arr = Object.entries(obj)var newobj = {}for (var i = 0; i < arr.length; i++){if(typeof arr[i][1] != 'object'){// 如果属性类型不是object,将属性添加到新对象中// 这里为什么不用toString()方法,很重要,下面会讲newobj[arr[i][0]] = arr[i][1]   } else {// 否则再次调用deepcopy函数(递归)newobj[arr[i][0]] = deepcopy(arr[i][1])}}// 返回新对象return newobj} else {// obj不是对象时返回函数或其它原始数据类型return obj}                  }newobj = deepcopy(obj)// console.log(newobj);newobj['c'] = 2newobj['d']['e'] = 5newobj['f'][0] = 9console.log(newobj); // newobj = {//     a : 1,//     b : 2,//     c : 2,//     d : {//         e : 5//     },//     f : [9,2,3]// }console.log(obj);// obj = { //     a : 1,//     b : 2,//     c : 3,//     d : {//         e : 4//     },//     f : [1,2,3]// }</script>
</body>
</html>

        为什么31行不再使用toString()方法判断属性是否为'[object, Object]',而使用typeof判断,是因为如果原对象中有属性值为数组的,如f : [1, 2, 3],需要使它进行递归使其进行深拷贝,因为数组是引用数据类型,如果不深拷贝,改变原对象里数组的值,新对象也会改变,这样就不算对象的深拷贝了。而且typeof 数组 和 typeof 对象 的值都是'object',这样判断能使数组和对象都进入else分支进行递归。

        如最后注释中的结果一样,改变新对象的属性值对旧对象不造成影响,反之亦然,两个对象互相独立。如此便完成了对对象的深拷贝。

  相关解决方案