js ES5和ES6 版本的对象深拷贝(JavaScript对象深拷贝)

偶尔我们会使用一下js对象的深拷贝

直接上代码

  1. 先准备一个需要拷贝的 对象
   var obj = {
           name:'小小叔',
           age:34,
           info: {
               hobby: ['travel', 'piano', {a:1}],
               career: {
                   teacher:4,
                   engineer:9
               }
           },
           fun(){
               console.log('一个方法');
           }
       }


   2. ES5 规范 版本 


       function deepCloneEs5 (origin, target) {
           var tar = target || {};
           var toStr = Object.prototype.toString;
           var arrType = '[object Array]';

           for(var k in origin){
               if (origin.hasOwnProperty(k)){
                   if (typeof origin[k] === 'object' && origin[k] !== null) {
                     tar[k] = toStr.call(origin[k]) === arrType ? [] : {};
                     deepCloneEs5(origin[k],tar[k])
                   } else {
                       tar[k] = origin[k];
                   }
               }
           }

           return tar;
       }




   3. ES6 版本


   // null undefined Date RegExp instanceof 

   // function 就先不理他,或者弄成字符串形式存着

   function deepCloneEs6 (origin,hashMap = new WeakMap()) {

   // 判断是不是 null和undefind (双== 可以两个同时判断,三===,是不行的) , 是不是对象 
       if (origin == undefined || typeof origin !== 'object') {
           return origin;
       }
       // 如果是一个日期类型的 返回一个日期
       if (origin instanceof Date) {
           return new Date(origin);
       }
       // 如果是正则类型的 返回正则
       if (origin instanceof RegExp) {
           return new RegExp(origin);
       }
       // 判断 健名是不是已经存在,也就是拷贝过了的健名,拷贝过了直接使用,就不再继续深拷贝
       const hashKey = hashMap.get(origin);
       if (hashKey) {
           return hashKey;
       }

       // 使用origin 的构造器来创建 target ,这样就不用去判断他是 [] 还是 {},
       // 例如 const arr = []; const arr2 = new arr.constructor(); arr是数组,arr2也会是数组
       // 例如 const obj = obj; const obj2 = new obj.constructor(); obj是对象,obj2也会是对象
       
       const target = new origin.constructor();
       // 这里把健名存入 hashMap
       hashMap.set(origin,target);
       for (let k in origin) {
           if (origin.hasOwnProperty(k)) {
               target[k] = deepCloneEs6(origin[k],hashMap);
           }
       }
       return target;
   }

4.例子实践
这个使用 ES6 规范的版本,主要是这个对象嵌套引用,得用 WeakMap 来优化一下

let test1 = {};
let test2 = {};
test2.test1 = test1;
test1.test2 = test2;

console.log(deepCloneEs6(test2));
posted @ 2022-06-09 10:50  S077星舰  阅读(285)  评论(0编辑  收藏  举报