深拷贝与浅拷贝的区别?如何手写实现一个深拷贝?
导语:
“深拷贝 VS 浅拷贝”是前端面试中绕不开的经典问题,既能考察 JavaScript 基础功,又能延伸至手写代码、递归、循环引用处理等进阶话题。本文从面试官视角解析其考察重点,并详解如何手写一个实用的深拷贝函数,助你面试中脱颖而出。
一、面试主题概述
在 JavaScript 中,引用类型(如对象、数组)在赋值或传参时常常引发“浅拷贝”或“深拷贝”的问题。尤其在 React、Vue 等响应式框架下,数据变化与状态同步息息相关,若不理解这两者的本质差异,很容易引发业务 bug。
本主题常作为基础知识或代码题出现,后续还可能结合闭包、原型、递归、JSON 等深入提问,是体现候选人代码能力和思维深度的优质考点。
二、高频面试题汇总
- 什么是浅拷贝和深拷贝?两者有什么区别?
- 哪些常见方法可以实现浅拷贝?
- 用 JSON 方法实现深拷贝有什么局限性?
- 如何手写一个通用的深拷贝函数?
- 深拷贝中如何处理循环引用问题?
三、重点题目详解
题目一:
什么是浅拷贝和深拷贝?举例说明。
const obj1 = { name: 'Tom', info: { age: 25 } };// 浅拷贝
const shallowCopy = Object.assign({}, obj1);
shallowCopy.info.age = 30;console.log(obj1.info.age); // 输出:30(原对象被影响)
解析:
- 浅拷贝:只拷贝对象的第一层属性,若属性为引用类型(如对象、数组),则拷贝的是引用地址。
- 深拷贝:递归拷贝所有层级的数据,原对象与拷贝对象彻底隔离。
题目二:
使用 JSON.parse(JSON.stringify())
实现深拷贝,有哪些问题?
const obj = {name: 'Tom',birthday: new Date(),func: () => {},undef: undefined,symbol: Symbol('s'),circular: null
};obj.circular = obj;const copy = JSON.parse(JSON.stringify(obj));console.log(copy); // 部分属性丢失
解析:
使用 JSON
方法虽然快捷,但存在以下缺陷:
- 函数、
undefined
、Symbol
类型会被忽略; Date
类型会变成字符串;- 不支持循环引用,会报错;
- 不适用于特殊对象如 Map、Set、RegExp。
面试官关注:
此题考察候选人是否对“工具函数的边界”有足够认识,避免在项目中使用时踩坑。
题目三:
如何手写一个支持循环引用的深拷贝函数?
function deepClone(obj, map = new WeakMap()) {if (obj === null || typeof obj !== 'object') return obj;if (map.has(obj)) return map.get(obj); // 处理循环引用let clone = Array.isArray(obj) ? [] : {};map.set(obj, clone); // 记录已克隆的对象for (let key in obj) {if (obj.hasOwnProperty(key)) {clone[key] = deepClone(obj[key], map);}}return clone;
}// 测试循环引用
const a = { name: 'A' };
a.self = a;const b = deepClone(a);
console.log(b); // 无堆栈溢出,成功复制
解析:
- 使用
WeakMap
缓存已拷贝对象,避免递归陷入死循环; - 判断基础类型直接返回;
- 使用
Array.isArray()
兼容数组和对象; - 保留引用结构,适合实际项目应用。
拓展建议:
- 若需支持更多类型(如
Date
、RegExp
、Map
、Set
等),可进行类型判断扩展; - 若对性能有高要求,需避免过度递归(例如处理大型嵌套结构时)。
四、面试官视角与加分项
考察目的:
- 是否理解 JS 中引用与内存的机制;
- 能否区别使用“引用复制”“浅拷贝”“深拷贝”三种方式;
- 能否用清晰逻辑实现一个通用工具函数,具备递归与边界处理能力;
- 在实际开发中是否具备“避免踩坑”的工程化思维。
如何加分:
- 回答时主动举出项目中出现“数据污染”的真实场景;
- 对性能考虑(是否滥用深拷贝)有思考;
- 能使用
WeakMap
处理循环引用,并说明其为何优于普通Map
; - 了解 Lodash、Rambda 等库中
cloneDeep
的实现方式。
五、总结与建议
- 深浅拷贝的本质在于“是否复制内存地址引用”;
- 浅拷贝适用于简单结构、性能敏感场景;
- 深拷贝适用于复杂嵌套数据,需谨慎使用以免性能损耗;
- 推荐封装自己的
deepClone
工具函数或使用成熟库,在项目中按需使用; - 面试中不仅要会用,更要能讲清楚“原理+场景+边界+优化”,才能拿下高分。
一句话记忆:
浅拷贝复制表面,深拷贝深入内核;JSON 简便却有限,循环引用用 WeakMap!
相关文章:
深拷贝与浅拷贝的区别?如何手写实现一个深拷贝?
导语: “深拷贝 VS 浅拷贝”是前端面试中绕不开的经典问题,既能考察 JavaScript 基础功,又能延伸至手写代码、递归、循环引用处理等进阶话题。本文从面试官视角解析其考察重点,并详解如何手写一个实用的深拷贝函数,助你…...
grafana 批量视图备份及恢复(含数据源)
一、grafana 批量视图备份 import requests import json import urllib3 import osfrom requests.auth import HTTPBasicAuthfilename_folders_map "folders_map.json" type_folder "dash-folder" type_dashboard "dash-db"# Grafana服务器地…...

SAP学习笔记 - 开发22 - 前端Fiori开发 数据绑定(Jason),Data Types(数据类型)
上一章讲了Icons(图标),Icon Explorer。 SAP学习笔记 - 开发21 - 前端Fiori开发 Icons(图标),Icon Explorer(图标浏览器)-CSDN博客 本章继续讲SAP Fiori开发的知识。 目录 1&…...

网络编程之TCP编程
基于 C/S :客户端(client)/服务器端(server) 1.流程 2. 函数接口 所有函数所需头文件: #include <sys/types.h> #include <sys/socket.h> 系统定义好了用来存储网络信息的结构体 ipv4通信使…...

C++进阶--C++11(04)
文章目录 C进阶--C11(04)lambdalambda表达式语法捕捉列表lambda的应用lambda的原理 包装器functionbind 总结结语 很高兴和大家见面,给生活加点impetus!!开启今天的编程之路!! 今天我们进一步c…...

当AI遇上防火墙:新一代智能安全解决方案全景解析
在2025年网络安全攻防升级的背景下,AI与防火墙的融合正重塑安全防御体系。以下三款产品通过机器学习、行为分析等技术创新,为企业提供智能化主动防护: 1. 保旺达数据安全管控平台——AI驱动的动态治理引擎 智能分类分级:基于…...
STL 库基础概念与示例
一、STL 库基础概念与示例 1. 容器分类 顺序容器 核心特性:按元素插入顺序存储,支持下标访问(类似数组),动态扩展内存。典型容器:vector(动态数组)。适用场景:需要频繁…...

Spring MVC参数绑定终极手册:单多参/对象/集合/JSON/文件上传精讲
我们通过浏览器访问不同的路径,就是在发送不同的请求,在发送请求时,可能会带一些参数,本文将介绍了Spring MVC中处理不同请求参数的多种方式 一、传递单个参数 接收单个参数,在Spring MVC中直接用方法中的参数就可以&…...

Fluence推出“Pointless计划”:五种方式参与RWA算力资产新时代
2025年6月1日,去中心化算力平台 Fluence 正式宣布启动“Pointless 计划”——这是其《Fluence Vision 2026》战略中四项核心举措之一,旨在通过贡献驱动的积分体系,激励更广泛的社区参与,为用户带来现实世界资产(RWA&am…...

innovus: ecoAddRepeater改变hier层级解决办法
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 来自星球提问: 星主,我在A/B/C/D/E/U0这个cell后面插入一个BUFF,生成的名字为A/B/C/BUFF1,少了D/E两个层级,不应该是生成A/B/C/…...

华为OD机试真题——硬件产品销售方案(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《硬件产品销售方案》: 目录…...
突破数据孤岛:StarRocks联邦查询实战指南
随着企业数据生态的复杂化,跨多个数据存储系统进行联合查询的需求日益增长。本文将深入解析如何利用StarRocks构建高效的数据联邦查询体系,实现与Apache Doris和Hive数据仓库的无缝对接。 ### 一、StarRocks联邦查询架构解析 StarRocks采用分布式架构设…...

传统业务对接AI-AI编程框架-Rasa的业务应用实战(1)--项目背景即学习初衷
我的初衷:我想学习AI。具体的方向是这样的:原本传统的平台业务去对接智能体。比如发票业务,发票的开具、审核、计税、回款等。根据用户在业务系统前台界面输入若干提示词 或者 语音输入简短语音信息,可以通过智能体给出需要处理的…...

低功耗架构突破:STM32H750 与 SD NAND (存储芯片)如何延长手环续航至 14 天
低功耗架构突破:STM32H750 与 SD NAND (存储芯片)如何延长手环续航至 14 天 卓越性能强化安全高效能效图形处理优势丰富集成特性 模拟模块实时监控保障数据完整性提升安全性与可靠性测量原理采样率相关结束语 在智能皮电手环及数据存储技术不…...
CSS选择子元素
通过选择器 为所有子元素应用样式。以下是几种常见方法: 1. 选择所有直接子元素(不包括孙级) css 复制 下载 .parent > * {/* 样式规则 */color: red; } > 选择器:只匹配直接子元素 * 通配符:匹配任意类型…...
git cherry-pick (28)
1.1 目的 本文档用于说明如何git上,通过cherry-pick命令合并某个功能。 将分支bg_device的 AHB New feature support libalgo arm64 lib 提交内容合并至 分支spfl_device 分支当中 1.2适配步骤 1.2.1 实操过程 > 分支sfpl_device的状态 rootxrootx-ThinkPad:~/workdir…...
android与Qt类比
一、概念对应关系 Android RecyclerView 组件类比描述Qt 模型 - 视图组件Qt 类比描述RecyclerView画板(容器)QAbstractItemView视图(展示数据的容器,如列表、表格)RecyclerView.Adapter画布(数据桥梁&…...
AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌
AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片 支持高清CMOS Sensor输入 国产品牌 产品概述: AX513CE 是一款针对模组渠道市场前端IPC应用而设计的数字SOC芯片,支持高清CMOS Sensor输入,经ISP处理、视频前处理以及音视频编…...

Linux(11)——基础IO(上)
目录 一、理解文件 二、回顾C文件的接口 📄 C语言文件操作函数表 编辑📄 三个文件流 三、系统文件I/O 1️⃣open 2️⃣close 3️⃣write 4️⃣read 四、文件描述符 💡用户操作文件的底层逻辑是什么? Ǵ…...

ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface
ABP-Book Store Application中文讲解 - Part 9: Authors: User Interface TBD 1. 汇总 ABP-Book Store Application中文讲解-汇总-CSDN博客 2. 前一章 ABP-Book Store Application中文讲解 - Part 8: Authors: Application Layer-CSDN博客 项目之间的引用关系。 目…...
鸿蒙开发修改版本几个步骤
鸿蒙开发修改版本几个步骤 比如:5.0.4(16)版本改为5.0.2(14)版本 一、项目下的build-profile.json5 "products": [{"name": "default","signingConfig": "default&qu…...

Hive自定义函数案例(UDF、UDAF、UDTF)
目录 前提条件 背景 概念及适用场景 UDF(User-Defined Function) 概念 适用场景 UDAF(User-Defined Aggregate Function) 概念 适用场景 UDTF(User-Defined Table-Generating Function) 概念 适…...

【学习笔记】Circuit Tracing: Revealing Computational Graphs in Language Models
Circuit Tracing: Revealing Computational Graphs in Language Models 替代模型(Replacement Model):用更多的可解释的特征来替代transformer模型的神经元。 归因图(Attribution Graph):展示特征之间的相互影响,能够追踪模型生成输出时所采用…...
3D视觉重构工业智造:解码迁移科技如何用“硬核之眼“重塑生产节拍
一、工业视觉的进化论:从CCD到3D相机的范式革命 在汽车冲压车间里,传统CCD相机正面临四大检测困局: 平面感知局限:二维视觉无法捕捉曲面工件形变环境适应性差:反光板件导致误检率超12%动态捕捉延迟:传送带…...
Elasticsearch中的刷新(Refresh)和刷新间隔介绍
在 Elasticsearch 中,刷新(Refresh) 是控制索引数据何时对搜索可见的机制,而 刷新间隔(Refresh Interval) 则是配置该机制执行频率的参数。理解这两个概念对于平衡搜索实时性与写入性能至关重要。 一、刷新(Refresh)的本质 Lucene 索引结构与搜索可见性Elasticsearch …...

STM32标准库-TIM定时器
文章目录 一、TIM定时器1.1定时器1.2定时器类型1.1.1 高级定时器1.1.2通用定时器1.1.3基本定时器 二、定时中断基本结构预分频器时器计时器时序计数器无预装时序计数器有预装时序RCC时钟树 三、定时器定时中断3.1 接线图3.2代码3.3效果: 四、定时器外部中断4.1接线图…...
【算法训练营Day05】哈希表part1
文章目录 哈希表理论基础有效的字母异位词两个数组的交集快乐数两数之和 哈希表理论基础 几个值得关注的知识点: hash表用于快速的判断元素是否存在(空间换时间)其原理就是将数据通过散列函数映射到bucket中,如果发生hash碰撞&a…...
CMap应用场景和例子
CMap 详解 CMap 是 MFC (Microsoft Foundation Classes) 库中的一个模板类,用于实现键值对的映射关系(类似哈希表或字典)。它提供了高效的数据存储和检索功能,适用于需要通过键快速查找值的场景。 基本模板参数 cpp 运行 tem…...

Kafka 如何保证顺序消费
在消息队列的应用场景中,保证消息的顺序消费对于一些业务至关重要,例如金融交易中的订单处理、电商系统的库存变更等。Kafka 作为高性能的分布式消息队列系统,通过巧妙的设计和配置,能够实现消息的顺序消费。接下来,我…...

【算法题】算法一本通
每周更新至完结,建议关注收藏点赞。 目录 待整理文章已整理的文章方法论思想总结模版工具总结排序 数组与哈希表栈双指针(滑动窗口、二分查找、链表)树前缀树堆 优先队列(区间/间隔问题、贪心 )回溯图一维DP位操作数学…...