浅拷贝和深拷贝均无法真正复制类实例的原型链、方法、私有字段或构造行为;浅拷贝仅提取可枚举属性生成普通对象,深拷贝虽隔离嵌套数据但仍退化为普通对象,真正克隆需类自身提供 clone() 或 from() 等语义化机制。

JavaScript 中浅拷贝与深拷贝对类实例的处理,本质上不是“能否拷贝”的问题,而是“是否保留实例类型和内部状态逻辑”的问题——两者都**无法真正复制类实例的原型链、方法、私有字段(#field)或构造行为**,但表现和后果不同。
浅拷贝对类实例:只提取可枚举属性,丢失一切“类的特征”
浅拷贝(如 Object.assign({}, instance)、{...instance}、structuredClone 除外)会遍历实例自身的可枚举属性,把它们的值(或引用)复制到一个普通对象中。原实例的 constructor、原型方法、Symbol 属性、私有字段、getter/setter 等全部丢失。
常见表现:
- 结果是一个 plain object(字面量对象),
instanceof MyClass返回 false - 调用原实例的方法(如
instance.sayHello())会报错:TypeError: instance.sayHello is not a function - 如果实例属性本身是对象或数组,其引用被直接复制——修改嵌套内容仍会影响原实例
深拷贝对类实例:多数方案仍退化为普通对象,少数能保留部分结构
标准深拷贝手段在类实例面前普遍“失效”:
-
JSON.parse(JSON.stringify()):直接丢弃函数、
undefined、Date、RegExp、Map/Set,类实例通常变成空对象{}或null -
structuredClone()(现代浏览器/Node.js 17+):支持
Date、Map、Set、ArrayBuffer等,但不保留类构造器和原型方法;结果仍是普通对象,只是嵌套数据被完整复制 -
手写递归 clone 函数:默认只处理
Object和Array,遇到类实例时若未特殊判断,会当作普通对象遍历——同样丢失类型和方法
真正保留类实例特征的方案:必须显式重建
若需保持实例类型、方法、私有状态甚至不可枚举属性,不能依赖通用拷贝,而要由类自身提供机制:
-
自定义
clone()方法:在类中实现,返回new MyClass(...)并手动复制关键字段(包括私有字段) -
使用
structuredClone+transfer或replacer配合反序列化逻辑:需配合类的静态from()方法,将克隆后的 plain data 转回实例 -
构造函数重实例化:仅适用于无副作用、纯数据类,且所有必要状态可通过参数传入(如
new MyClass(instance.x, instance.y))
一句话总结关键差异
浅拷贝让类实例“变扁”成普通对象,且嵌套引用共享;深拷贝让嵌套数据也独立,但依然无法恢复类的身份与行为——二者都输出 plain object,区别只在嵌套层级是否隔离;要真正复制实例,必须靠类自己定义语义化的克隆逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











