如何实现一个深拷贝函数?

在项目开发中,如何实现一个深拷贝函数?

阅读 176
3 个回答

深拷贝是指创建一个新对象,完全复制原对象的所有属性,包括嵌套的对象和数组。

示例代码

function deepClone(obj) {
    if (typeof obj !== 'object' || obj === null) return obj;
    let result = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            result[key] = deepClone(obj[key]);
        }
    }
    return result;
}
const obj = { a: 1, b: { c: 2 } };
const clonedObj = deepClone(obj);

口语化解释:这个函数通过递归遍历对象的属性,如果是对象或数组就继续递归,直到所有嵌套的属性都被复制。这样可以避免浅拷贝带来的引用共享问题。

function myDeepClone(obj: any) {
    return structuredClone(obj);
}

手动狗头🐶

// 方法1:使用JSON - 简单但有局限性
function deepCloneJSON(obj) {
  return JSON.parse(JSON.stringify(obj));
}

// 方法2:递归实现 - 处理常见数据类型
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  
  // 处理日期对象
  if (obj instanceof Date) {
    return new Date(obj);
  }
  
  // 处理数组
  if (Array.isArray(obj)) {
    return obj.map(item => deepClone(item));
  }
  
  // 处理普通对象
  const clonedObj = {};
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      clonedObj[key] = deepClone(obj[key]);
    }
  }
  
  return clonedObj;
}

// 方法3:增强版 - 处理更多特殊情况和循环引用
function deepCloneAdvanced(obj, hash = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }
  
  // 处理循环引用
  if (hash.has(obj)) {
    return hash.get(obj);
  }
  
  // 处理日期
  if (obj instanceof Date) {
    return new Date(obj);
  }
  
  // 处理正则
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  
  // 处理特殊对象类型
  if (obj instanceof Map) {
    const map = new Map();
    hash.set(obj, map);
    obj.forEach((value, key) => {
      map.set(key, deepCloneAdvanced(value, hash));
    });
    return map;
  }
  
  if (obj instanceof Set) {
    const set = new Set();
    hash.set(obj, set);
    obj.forEach(value => {
      set.add(deepCloneAdvanced(value, hash));
    });
    return set;
  }
  
  // 处理数组和普通对象
  const clone = Array.isArray(obj) ? [] : {};
  
  // 存储引用,避免循环引用导致的栈溢出
  hash.set(obj, clone);
  
  // 复制所有属性
  Reflect.ownKeys(obj).forEach(key => {
    clone[key] = deepCloneAdvanced(obj[key], hash);
  });
  
  return clone;
}

// 方法4: 使用 lodash 库的 cloneDeep
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题