对象的深拷贝

120 阅读1分钟

使用JSON.stringify()

let copyObj=JSON.parse(JSON.stringify(obj));

缺陷:不可枚举属性复制不了,属性值是Symbol,函数,日期对象,正则表达式不能正确复制

使用递归

实现一个完整的深拷贝需要考虑到很多边界情况,对于特殊的引用类型有拷贝需求的话,建议使用第三方库

常见要求:

  • 拷贝自身可枚举属性
    • 属性值是基本类型或null
      直接使用赋值操作就行
    • 属性值是Symbol
      copyObj[key]=Symbol.for(key);
    • 属性值是数组
      循环,每个值调用深拷贝函数
    • 属性值是函数,日期对象,正则表达式
      cloneObj=new obj.constructor(obj)
  • 拷贝自身不可枚举属性(Symbol类型键...
    首先拿到不可枚举属性,在逐一添加到cloneObj的不可枚举属性
  • 拷贝原型上可枚举属性,不可枚举属性
    只要保证拷贝后的对象cloneObj和拷贝前的对象obj是同一个class创建出来的就行
    cloneObj=new obj.constructor;
  • 循环引用也可以拷
    需要借助map记录已经拷贝好的键值对
//以下代码仅实现原型链属性拷贝,自身可枚举属性拷贝2
function deepClone(obj){
  if(typeof obj!=='object' || obj==null) return obj;
  if(obj instanceof RegExp || obj instanceof Date || obj instanceof Function){
    return new obj.constructor(obj);
  }
  let cloneObj=new obj.constructor;
  for(let key in obj){
    if(obj.hasOwnProperty(key)){
      newObj[key]=deepClone(obj[key]);
    }
  }
  return cloneObj;
}

使用第三方库

lodash 一劳永逸解决深克隆问题...