【前端每天一题】🔥 第 10 题:浅拷贝 vs 深拷贝?如何手写深拷贝?

浅拷贝 vs 深拷贝 - 前端高频面试题

第 10 题:浅拷贝 vs 深拷贝?如何手写深拷贝?

第 10 题:浅拷贝与深拷贝的区别?如何实现深拷贝?


一、浅拷贝(Shallow Copy)

⭐ 定义

只拷贝第一层,遇到引用类型只拷贝引用地址。

也就是说:

  • 修改子对象,会影响原对象
  • 只复制外壳,不复制内部结构

⭐ 常见浅拷贝方式

javascript 复制代码
const obj2 = { ...obj1 }
const obj2 = Object.assign({}, obj1)
const arr2 = arr1.slice()
const arr2 = arr1.concat()

二、深拷贝(Deep Copy)

⭐ 定义

完全复制一个新对象,所有嵌套内容都会被复制,不共享引用。

修改副本不会影响原对象。


三、最常见的深拷贝方式:JSON 深拷贝

javascript 复制代码
let newObj = JSON.parse(JSON.stringify(obj))

✔ 优点

  • 简单粗暴好用
  • 适合面试聊天开头用

❌ 缺点(必须要说)

  • 会丢失 undefined
  • 会丢失 symbol
  • 会丢失 function
  • 无法拷贝 Map/Set
  • 无法拷贝原型链
  • 日期会变成字符串

这段话一定要背熟,面试官听了会点头。


四、真正能用的深拷贝:手写递归版本

面试官: "那你能手写一个深拷贝吗?"

你写下面版本就能给他干沉默。

⭐ 手写深拷贝(可处理循环引用 + 基本类型)

javascript 复制代码
function deepClone(target, map = new WeakMap()) {
  // 基础类型或 null,直接返回
  if (typeof target !== 'object' || target === null) {
    return target
  }

  // 处理循环引用
  if (map.has(target)) {
    return map.get(target)
  }

  // 处理数组或对象
  const clone = Array.isArray(target) ? [] : {}
  map.set(target, clone)

  for (let key in target) {
    if (target.hasOwnProperty(key)) {
      clone[key] = deepClone(target[key], map)
    }
  }

  return clone
}

⭐ 可以克隆:

  • 对象
  • 数组
  • 嵌套结构
  • 循环引用

❌ 不支持:

  • Date
  • RegExp
  • Map / Set
  • Function 的拷贝细节(一般不需要拷贝函数)

但!!面试 95% 情况下够用了。


五、高级版(面试官:嗯?你写得不错啊)

如果你想进一步加分,可以说:

"如果需要完整 deepClone,我会专门写对 Date、RegExp、Map、Set 的处理逻辑。"

如:

javascript 复制代码
if (target instanceof Date) return new Date(target)
if (target instanceof RegExp) return new RegExp(target)

六、浅拷贝 vs 深拷贝(记忆图表)

比较点 浅拷贝 深拷贝
拷贝层级 第一层 所有层
内部对象是否共享? 共享引用 各自独立
常用方法 ...Object.assign 递归、JSON、第三方库

七、速记卡片(背这个就够了)

typescript 复制代码
📌 浅拷贝:只复制第一层,引用类型共享地址
📌 深拷贝:完全复制,不共享引用

浅拷贝方法:
- {...obj}
- Object.assign()
- slice / concat

JSON 深拷贝:
- 简单但会丢失:undefined / function / symbol / 日期 / 原型 / Map Set

手写深拷贝:
- 递归 + WeakMap 处理循环引用
相关推荐
前端一课1 小时前
【前端每天一题】🔥 第 8 题:什么是事件委托?它的原理是什么?有哪些优点和常见坑? - 前端高频面试题
前端·面试
前端一课1 小时前
【前端每天一题】🔥第7题 事件冒泡与事件捕获 - 前端高频面试题
前端·面试
前端一课1 小时前
【前端每天一题】 第 5 题:Promise.then 执行顺序深入题(微任务队列机制)
前端·面试
前端一课1 小时前
【前端每天一题】🔥 事件循环第 6 题:setTimeout(fn, 0) 执行时机详解
前端·面试
前端一课1 小时前
【前端每天一题】🔥 第3题 事件循环 20 道经典面试题(附详细答案)
前端·面试
前端一课1 小时前
【前端每天一题】第 2 题:var、let、const 的区别?(绝对高频)
前端·面试
前端一课1 小时前
【前端每天一题】🔥第四题 原型与原型链 - 前端面试必考题
前端·面试
初见0012 小时前
告别无限循环:深入理解并征服 React Hooks 的依赖数组
前端
一颗不甘坠落的流星2 小时前
【HTML】iframe 标签 allow 权限汇总(例如添加复制粘贴权限)
前端·javascript·html