浅拷贝只复制第一层属性引用,修改嵌套对象会影响原对象;深拷贝递归复制所有层级,确保完全独立。常见浅拷贝方法有Object.assign()、展开运算符等,但无法处理嵌套、Symbol、不可枚举属性及特殊类型;深拷贝可用JSON方法(限制多)、structuredClone(现代推荐)、手写递归(需防循环引用)或Lodash的_.cloneDeep(生产常用)。实际应用中需注意性能开销、循环引用崩溃、不可序列化值丢失、原型链断裂及getter/setter失效等陷阱。
JavaScript 中的浅拷贝只复制对象第一层属性的引用,深拷贝则递归复制所有层级,确保新旧对象完全独立。关键区别在于:修改拷贝后的对象是否会影响原对象——浅拷贝会,深拷贝不会。
常用方法包括 Object.assign()、展开运算符 {...obj}、Array.prototype.slice() 和 Array.from()。它们都只处理第一层:
null、undefin
ed、函数、正则、Date 等特殊值时行为不一致(如 Object.assign() 会跳过 undefined,但展开运算符会报错)没有一种方案完美适配所有场景,需按需求选择:
JSON.parse(JSON.stringify(obj)) —— 快速有效,但会丢失函数、undefined、Symbol、Date、RegExp、NaN、Infinity,且无法处理循环引用structuredClone(obj) —— 原生支持大多数类型(含 Map、Set、Date、RegExp、ArrayBuffer),能处理循环引用,但目前部分老环境不支持_.cloneDeep() 经过大量边界测试,兼容性好,支持各种边缘类型和循环引用深拷贝不是“一劳永逸”的操作,实际中常踩这些坑:
不复杂但容易忽略。选方案前先问自己:要拷什么类型?运行环境支持哪些 API?是否允许丢属性?性能敏感吗?