对象拷贝的关键是安全实现,需区分引用与值:浅拷贝仅复制顶层,嵌套仍共享地址;深拷贝递归新建全部层级,推荐structuredClone()或定制方案;Java需显式实现Cloneable或序列化。

对象拷贝不是“要不要做”的问题,而是“怎么做才安全”的问题。核心在于理解引用与值的区别——基本类型赋值是复制值,引用类型赋值是复制地址。一旦忽略这点,修改一个对象就可能意外影响另一个,尤其在状态管理、表单暂存、API响应缓存等场景中极易引发隐蔽 bug。
浅拷贝:复制顶层,共享嵌套
浅拷贝只创建新对象,把原对象第一层属性的值(或引用)照搬过去。对基本类型没问题,但所有嵌套的对象、数组仍共用同一内存地址。
-
常用方法:扩展运算符
{...obj}、Object.assign({}, obj)、Array.from(arr)或[...arr] -
典型陷阱:修改
copy.objProp.field会同步反映到原对象,因为objProp是引用共享 - 适用情况:数据结构扁平(无嵌套)、仅需临时读取、性能敏感且确认不改深层内容
深拷贝:逐层新建,彻底隔离
深拷贝递归遍历整个对象树,为每个嵌套对象/数组分配新内存,确保修改副本完全不影响原始数据。
-
简单但有局限:
JSON.parse(JSON.stringify(obj))—— 不支持函数、undefined、Date、RegExp、Symbol、循环引用,会丢失原型链 -
更健壮的选择:使用
structuredClone()(现代浏览器及 Node.js ≥17.0),原生支持 Map、Set、Date、RegExp、ArrayBuffer 等,且能处理循环引用 -
自定义需求时:手写递归函数或借助 Lodash 的
cloneDeep(),可控制特殊类型处理逻辑(如忽略某些字段、转换日期格式)
Java 中的拷贝机制要点
Java 没有语言级深拷贝语法,必须显式实现:
-
浅拷贝:实现
Cloneable接口并重写clone()方法(默认行为),但仅复制本层字段 -
深拷贝:在
clone()中手动克隆所有引用字段,或采用序列化方式(对象及其所有字段需实现Serializable) -
注意:
transient字段不会被序列化;不可序列化的类会抛出异常;String 因其不可变性,在浅拷贝中表现类似值类型
选择策略:看结构、看环境、看代价
没有“最好”的拷贝方式,只有“最合适”的选择:
- 纯数据对象 + 现代运行时 → 优先用
structuredClone() - 需要兼容旧环境 + 结构简单 →
JSON.parse(JSON.stringify())加校验兜底 - 复杂业务对象 + 需定制逻辑 → 封装专用 clone 方法或使用成熟工具库
- Java 场景 → 根据是否需跨进程/网络传输决定用 clone 还是序列化

















