前端面试题 - 65. 手写的深拷贝函数 deepClone,可以实现任意 JS 数据类型的深拷贝

198 阅读1分钟
function deepClone(obj, clonedMap = new WeakMap()) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }
  
  // 缓存避免循环引用
  if (clonedMap.has(obj)) {
    return clonedMap.get(obj);
  }
  
  // 正则表达式对象
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
    
  // 日期对象
  if (obj instanceof Date) {
    return new Date(obj.getTime());
  }

  let clone = Array.isArray(obj) ? [] : {};

  clonedMap.set(obj, clone);
  // 递归拷贝
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key], clonedMap);
    }
  }

  return clone;
}

使用方法:

const obj = {
  name: 'Tom',
  age: 18,
  hobbies: ['reading', 'music'],
  friends: {
    name: 'Jerry',
    age: 20
  }
};
const newObj = deepClone(obj);

需要注意的是,在递归拷贝对象或数组中的每一项时,需要判断该项的数据类型。如果是对象或数组,就递归调用 deepClone 函数进行深度拷贝;如果是基本数据类型,就直接赋值给新对象或数组。同时,需要注意原始数据类型和引用数据类型的拷贝方式不同。