📚 浅拷贝 vs 深拷贝:前端面试解析 
TIP
这是一份完整的浅拷贝与深拷贝面试指南
🔍 常见问题 
1. 什么是浅拷贝和深拷贝?
| 拷贝类型 | 定义 | 特点 | 
|---|---|---|
| 浅拷贝 | 只复制第一层属性 | ✅ 性能好 ❌ 引用类型共享  | 
| 深拷贝 | 递归复制所有层级 | ✅ 完全独立 ❌ 性能开销大  | 
2. 实现浅拷贝的方法
javascript
// 方法一:基础循环实现
function shallowCopy(obj) {
  if (typeof obj !== 'object' || obj === null) return obj;
  const newObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = obj[key];
    }
  }
  return newObj;
}
// 方法二:Object.keys实现
const shallowCopy2 = obj => {
  if (typeof obj !== 'object' || obj === null) return obj;
  const newObj = Array.isArray(obj) ? [] : {};
  Object.keys(obj).forEach(key => {
    newObj[key] = obj[key];
  });
  return newObj;
}
// 测试用例
const obj = { 
  name: '浅拷贝',
  info: { age: 18 }
};
const copyObj = shallowCopy(obj);
obj.info.age = 20;
console.log(copyObj.info.age); // 20 - 说明是浅拷贝🎯 深拷贝实现 
手写深拷贝 
从简单到复杂的实现
javascript
// 基础版本 - 只处理基本类型和对象/数组
function simpleDeepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) return obj;
  const newObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = simpleDeepCopy(obj[key]);
    }
  }
  return newObj;
}JSON 方法的局限性 
- [ ] 无法处理循环引用
 - [ ] 无法复制函数
 - [ ] 无法处理 
undefined和Symbol - [ ] 特殊对象处理失败 
DateRegExpError
 - [ ] 丢失原型链
 
深拷贝难点 
mindmap
  root((深拷贝难点))
    循环引用
      WeakMap记录
      防止死循环
    特殊对象
      Date
      RegExp
      Map/Set
    原型链
      getPrototypeOf
      create继承
    属性类型
      Symbol键
      不可枚举属性
完整的深拷贝实现 
生产级别的深拷贝实现
javascript
/**
 * @typedef {Object} Options
 * @property {WeakMap} [hash] - 用于处理循环引用的 WeakMap
 */
/**
 * 完整的深拷贝实现
 * @param {*} obj - 要拷贝的对象
 * @param {Options} [options] - 配置选项
 * @returns {*} 深拷贝后的对象
 */
function completeDeepCopy(obj, hash = new WeakMap()) {
  // 基础类型直接返回
  if (obj === null || typeof obj !== 'object') return obj;
  
  // 处理特殊对象
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);
  
  // 检测循环引用
  if (hash.has(obj)) return hash.get(obj);
  
  // 获取对象所有属性描述符
  const allDesc = Object.getOwnPropertyDescriptors(obj);
  // 创建一个新对象,并继承原型链
  const clone = Object.create(Object.getPrototypeOf(obj), allDesc);
  
  // 记录已拷贝过的对象
  hash.set(obj, clone);
  
  // 递归拷贝所有属性
  for (let key of Reflect.ownKeys(obj)) {
    clone[key] = completeDeepCopy(obj[key], hash);
  }
  
  return clone;
}📝 面试答题要点 
核心要点 
区分概念
- [x] 浅拷贝与深拷贝的本质区别
 - [x] 内存模型的差异
 
实现方法
- [x] 浅拷贝的多种实现
 - [x] 深拷贝的不同方案
 
深拷贝难点
graph TD A[深拷贝难点] --> B[循环引用] A --> C[特殊对象] A --> D[原型链] A --> E[描述符] B --> F[WeakMap解决] C --> G[instanceof判断] D --> H[Object.create] E --> I[getOwnPropertyDescriptors]
🚀 进阶知识点 
WeakMap 的作用 
IMPORTANT
WeakMap 在深拷贝中扮演着关键角色
- 存储对象映射关系
 - 防止内存泄漏javascript
const hash = new WeakMap(); // WeakMap 的键是弱引用,不会阻止垃圾回收 
Reflect.ownKeys 的优势 
javascript
const obj = {
  [Symbol('key')]: 'value',
  normal: 'normal'
};
// ✅ 获取所有类型的键
console.log(Reflect.ownKeys(obj));
// 输出: ['normal', Symbol(key)]属性描述符示例 
javascript
const obj = {
  get value() { return this._value; },
  set value(val) { this._value = val; }
};
const desc = Object.getOwnPropertyDescriptor(obj, 'value');
console.log(desc);
/* 输出:
{
  get: [Function: get value],
  set: [Function: set value],
  enumerable: true,
  configurable: true
}
*/