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 中是怎麼實現的?去看看
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章