从知乎看到的简单的深拷贝的方法

*** 如果涉及复杂的深拷贝,还是要使用loadDash的cloneDeep方法
其实还是没有考虑到functionsymbol之类的类型,可能会有bug
而且浅拷贝使用
JSON.parse(JSON.stringfy(obj))
或者ES6的
Object.assgin(newObj, oldObj)
再或者ES6的解构赋值语法
const newObj = {...oldObj}

/**
 * 知乎上看到的,原答案如下
 */
// function cloneDeep (obj){
//   // 1.判断是否为null 或undefined
//   if (typeof obj == null ) return obj;
//   // 2.判断是否为日期Date
//   if (obj instanceof Date) return new Date(obj);
//   // 3.判断是否为正则 typeof /\d+/ === 'object'
//   if (obj instanceof RegExp) return new RegExp(obj);
//   // 4.如果不是数组或对象,返回该值
//   if (typeof obj !== 'object') return obj;
//   // 接下来,要么是对象,要么是数组 可以用 new obj.constructor得到它类型的空值
//   let cloneObj = new obj.constructor;
//   for (const key in obj) {
//     if (obj.hasOwnProperty(key)) {
//       // 递归深拷贝
//       cloneObj[key] = cloneDeep(obj[key]);
//     }
//   }
//   return cloneObj;
// }

// let obj = {aa: {bb: 123}}
// let cloneObj = cloneDeep(obj);
// obj.aa.bb = 321;
// console.log(obj);
// console.log(cloneObj);


function cloneDeep(obj) {
  // 确保参数为对象类型
  if (obj == null ||
    obj == undefined ||
    typeof obj == null ||
    typeof obj !== 'object' ||
    obj instanceof Date ||
    obj instanceof RegExp
  ) return obj;
  // 然后参数肯定是对象或是数组(因为数组在js中叫做数组对象,本身也是对象)
  let cloneObj = new obj.constructor;
  // 开始递归复制
  for (const key in obj) {
    // 因为hasOwnProperty属性可能会被改写,使用call保证调用继承来的属性
    if (Object.hasOwnProperty.call(obj, key)) {
      cloneObj[key] = cloneDeep(obj[key]);
    }
  }
  return cloneObj;
}


var oldObj = {
  aa: 1,
  bb: {
    cc: 2,
    dd: [11,22,33]
  },
  ee: Date.now(),
  ff: 'amigo',
  gg: ['nice', 'good', 'bravo']
}

var newObj = cloneDeep(oldObj);
console.log(oldObj);
console.log(newObj);
console.log('======');
newObj.bb.dd = ['facebook', 'twitter'];
newObj.ff = 'aloha';
console.log(oldObj);
console.log(newObj);
posted @ 2021-06-02 11:37  Aienming  阅读(98)  评论(0)    收藏  举报