001[Js修炼]手写深拷贝

/**
// 编写一个深度克隆函数,满足以下需求(此题考察面较广,注意细节)
function deepClone(obj) {}

// deepClone 函数测试效果
const objA = {
  name: 'jack',
  birthday: new Date(),
  pattern: /jack/g,
  body: document.body,
  others: [123, 'coding', new Date(), /abc/gim],
};

const objB = deepClone(objA);
console.log(objA === objB); // 打印 false
console.log(objA, objB); // 对象内容一样

*/
@解法:jayce
function deepClone(obj) {
  const cloneObj = {};
  if (Object.keys(obj).length > 0) {
    for (let i in obj) {
      const type = isType(obj[i]);
      if (['String', 'Number', 'Boolean', 'Undefined', 'Null'].includes(type)) {
        cloneObj[i] = obj[i];
      } else if (['RegExp', 'Date', 'Array'].includes(type)) {
        const cStruct = Object.getPrototypeOf(obj[i]).constructor;
        cloneObj[i] = Reflect.construct(cStruct, [obj[i]]);
      } else if (type === 'HTMLBodyElement') {// 这里考虑去换作nodeType === 1 ,这样可以匹配所有元素节点
        cloneObj[i] = obj[i].cloneNode();
      } else if (type === 'Object') {
        cloneObj[i] = deepClone(obj[i]);
      } else {
        throw new Error(
          `${type} is currently not matched!! need add the type!`,
        );
      }
    }
  }

  function isType(target) {
    return Object.prototype.toString.call(target).split(/\W/)[2];
  }
  return cloneObj;
}

const objB = deepClone(objA);
console.log(objA === objB); // 打印 false
console.log(objA, objB); // 对象内容一样

// TODO:

  1. 考虑更多解法, 例如使用 call/apply 去替换 反射方法
  2. 不用构造函数怎么解?
  3. 类型判断 loadash/ vueUse 中是怎么实现的?去看看
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章