【前端每天一题】🔥 第 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 处理循环引用
相关推荐
鬼手点金8 小时前
nanoGPT/nanochat 能做出 DeepSeek/Qwen 这样的大模型吗?
服务器·前端·javascript·bug·openclaw
蛋蛋的就会顺顺的8 小时前
hot100 p0——栈,贪心算法,动态规划
java·前端·javascript·算法·leetcode·力扣
程序员Sunday9 小时前
TypeScript 的 any、unknown、never 有什么区别?
前端·面试·typescript
朱涛的自习室9 小时前
70 美金的 Beyond Compare,我让 Gemini 4 和 DeepSeek 造个开源免费版(Day 2)
android·前端·人工智能
小 黄 鸡9 小时前
HashMap 面试必会知识点详解(JDK 8)
java·面试·职场和发展
码艺-Alimjan9 小时前
Tauri 源码备份 · 打包 & 解压 总结,源码收集之路
前端·javascript·vue.js
小马不起床9 小时前
零基础玩转 FastAPI_11:前端后台管理页面
前端·状态模式·fastapi
子非鱼a11 小时前
【文件上传】一个普普通通的edu16
前端
美狐美颜SDK开放平台11 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
pride.li12 小时前
第03章 Python 教程-基础语法:注释与变量
服务器·前端·后端·python·算法·计算机视觉