【前端每天一题】🔥 第 17 题:什么是浅拷贝与深拷贝?如何实现深拷贝?

下面是 下一道高频前端面试题(第 17 题:深拷贝与浅拷贝)

继续保持:详细版 + 速记卡片


✅ 第 17 题:什么是浅拷贝与深拷贝?如何实现深拷贝?

这是前端必考题,答案必须结构化、带例子。


📘 一、浅拷贝(Shallow Copy)

只复制第一层属性,对象内嵌的对象仍然引用同一个地址。

常见浅拷贝方式:

1)Object.assign()

ini 复制代码
const obj = { a:1, b:{ c:2 } }
const copy = Object.assign({}, obj)

copy.b.c = 999
console.log(obj.b.c) // 999,被影响

2)扩展运算符 ...

go 复制代码
const copy = { ...obj }

3)Array.prototype.slice / concat

ini 复制代码
const arr = [1, {x:2}]
const copy = arr.slice()
copy[1].x = 999
console.log(arr[1].x) // 999

结论:浅拷贝只复制第一层,嵌套对象仍共享引用。


📘 二、深拷贝(Deep Copy)

将所有层级的数据复制,不共享引用。


📘 三、深拷贝方法大全


🚀 方法 1:JSON.parse(JSON.stringify())

ini 复制代码
const obj = { a:1, b:{ c:2 } }
const copy = JSON.parse(JSON.stringify(obj))

👍 优点:简单、常用

⚠️ 缺点:

  • 无法拷贝 function
  • 无法拷贝 undefined
  • 无法拷贝 symbol
  • 无法处理循环引用

🚀 方法 2:结构化克隆(现代浏览器最推荐)

ini 复制代码
const clone = structuredClone(obj)

👍 支持:

  • Date / RegExp
  • Map / Set
  • 深层嵌套
  • 循环引用

⚠️ 不支持 function


🚀 方法 3:手写深拷贝(必会面试代码)

go 复制代码
function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj

  if (map.has(obj)) return map.get(obj)

  const copy = Array.isArray(obj) ? [] : {}
  map.set(obj, copy)

  for (let key in obj) {
    copy[key] = deepClone(obj[key], map)
  }
  return copy
}

const newObj = deepClone(oldObj)

👍 能力最强:可以处理循环引用 + 深层结构

⚠️ 不处理 function / Symbol 需要额外补强


🚀 方法 4:第三方库 Lodash.cloneDeep

go 复制代码
const copy = _.cloneDeep(obj)

👍 稳定,功能完备

⚠️ 项目里不一定允许使用


📘 四、浅拷贝 vs 深拷贝 总结表

对比点 浅拷贝 深拷贝
是否复制所有层级? ❌ 否 ✅ 是
是否共享引用? ✅ 是 ❌ 否
常见方法 Object.assign / ... JSON / structuredClone / 手写递归
性能 相对慢
是否能处理循环引用 ❌ 否 structuredClone / 手写可处理

📘 五、速记卡片(面试背诵版)

diff 复制代码
🎯浅拷贝:只复制第一层,嵌套对象共用引用
- Object.assign
- 扩展运算符 ...
- slice / concat

🎯深拷贝:复制所有层级,不共享引用
- JSON.parse(JSON.stringify()) → 快速但有限
- structuredClone() → 最强官方方案
- 手写 deepClone() → 面试必会
- lodash.cloneDeep → 工程可用

核心:深拷贝要解决循环引用 + 各种类型处理

第 18 题将是:防抖(debounce)与节流(throttle)区别与实现。

相关推荐
donecoding14 分钟前
Corepack 完全解析:从懵到懂,包管理器自由了
前端·node.js·前端工程化
yqcoder18 分钟前
端经典面试题:为什么 0.1 + 0.2 !== 0.3?
前端·css
ZC跨境爬虫23 分钟前
跟着 MDN 学 HTML day_12:(HTML网页图片嵌入)
前端·javascript·css·ui·html
knight_9___27 分钟前
LLM工具调用面试篇5
人工智能·python·深度学习·面试·职场和发展·llm·agent
光影少年28 分钟前
reeact虚拟DOM、Diff算法原理、key的作用与为什么不能用index
前端·react.js·掘金·金石计划
用户0595401744633 分钟前
大模型记忆存储踩坑实录:LangChain 的 ConversationBufferMemory 让我排查了 6 小时
前端·css
是上好佳佳佳呀40 分钟前
【前端(十二)】JavaScript 函数与对象笔记
前端·javascript·笔记
Zik----42 分钟前
操作系统核心考点(面试/期末复习)
面试·操作系统·研究生面试·期末复习专业课计算机
你真的快乐吗1 小时前
@fuxishi/svg-icon:一个 Vue 3 svg本地图标+iconify图标组件库,让图标管理不再头疼
前端·vue.js·typescript
Rkgua1 小时前
ESModule和Commonjs模块的区别
前端·javascript