深浅拷贝

132 阅读1分钟

深拷贝和浅拷贝

Description

深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。
浅拷贝
    for in;
    Object.assign.
    ...,
    Array.prototype.slice(),
    Array.prototype.concat()等
深拷贝
  1.  JSON.parse(JSON.stringify(obj,filter|[],format:"\n"), function (key, val) {return val })
    
  • 函数无法拷贝
  • 原型链上的属性无法拷贝
  • 不能正确的处理 Date 类型的数据
  • 不能处理 RegExp
  • 会忽略 symbol undefined
  1.  function deepClone(target,weakMap=new WeakMap()){
         if(target instanceof RegExp) return new RegExp(target);
         if(target instanceof Date) return new Date(target);
         if(target===null||typeof target !=='object') return target;
         if(weakMap.has(target)) return weakMap.get(target);//弱引用释放内存
         let instance=new target.constructor();//原型链上继承
         weakMap.set(target,instance);
         <!-- for(let key in target){
             if(target.hasOwnProperty(key)) instance[key]=deepClone(target[key],weakMap);
         } -->
         //包含symbol
         let keys= Reflect.ownKeys(target);
         // 获取源对象所有属性描述符
        
         for(let index in keys){
             let key=keys[key];
             instance[key]=deepClone(target[key],weakMap);
         }
         //设置访问器
         let descriptor = Object.getOwnPropertyDescriptors(target);
         Object.defineProperties(instance,descriptor);
         
         return instance;
     }
     function deepClone(target){
         if(target instanceof RegExp) return new RegExp(target);
         if(target instanceof Date) return new Date(target);
         if(target===null||typeof target !=='object') return target;
         let cloneTarget =  Array.isArray(target) ? [] : {};
         for (let key in target) {// 可枚举属性,包括自有属性、继承自原型的属性
             cloneTarget[key] = deepClone(target[key])
         }
         return cloneTarget;
     }
     <!-- 自定义返回值-->
     function deepClone(target,callback){
         if(typeof callback!=='function'){
             callback = function (key, val,target) { return val; }
         }
         if(target instanceof RegExp ||target instanceof Date||(target===null||typeof target !=='object') ) return callback(undefined,target);
         let cloneTarget =  Array.isArray(target) ? [] : {};
         // forEach|keys 对象自有的可枚举属性
         // getOwnPropertyNames 对象的自有属性,包括可枚举和不可枚举的
         // Reflect.ownKeys (target) :Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。
         for (let key in target) {// 原型属性和自身 可枚举属性
             cloneTarget[key] = deepClone(callback(key,target[key],target));
         }
         return cloneTarget;
    
     }