最优雅的方式是直接用structuredclone,它原生保留原型链、支持循环引用且类型判断正常;旧环境需手写深拷贝并用object.create还原原型;设计上应降低原型依赖,优先使用鸭子类型和纯函数。

最优雅的方式是直接用 structuredClone——它原生保留原型链,一行代码解决,无需手动干预。
优先用 structuredClone(现代环境首选)
这是目前唯一被标准支持、开箱即用的原型链安全方案:
- 拷贝后的 Date、RegExp、Map、Set 等仍是对应类型,
instanceof判断完全正常 - 自定义类实例只要构造器可访问(非闭包私有),其原型链也会完整保留
- 自动处理循环引用,不抛错也不卡死
- 不支持函数、
undefined、Symbol和WeakMap/WeakSet——这是规范限制,不是缺陷,生产中应避免依赖这些参与拷贝
兼容旧环境时需手动重建原型
当必须支持 IE 或老版 Node.js,手写深拷贝不能只复制属性,关键在实例化阶段还原继承关系:
- 用
Object.create(obj.constructor.prototype)创建新对象,而非{}或Object.assign({}, obj) - 对内置类型(如
Date、RegExp、Array)单独判断,调用对应构造器:例如new Date(obj)、new RegExp(obj) - 避免直接赋值
copy.__proto__ = obj.__proto__——非标准、严格模式下可能失败,且对Object.freeze()对象无效 - 若目标类有静态方法或 Symbol 属性,需额外通过
Object.getOwnPropertyDescriptors同步到新实例或构造器上
从设计源头降低原型依赖风险
与其反复修补拷贝逻辑,不如让对象本身更“可拷贝”:
- 用鸭子类型代替
instanceof:检查obj.getDate是否为函数,而非obj instanceof Date - 把核心逻辑抽成纯函数,接收原始数据(如时间戳、正则字符串)而非实例
- 为自定义类提供
toJSON()和静态fromJSON()方法,让序列化路径可控 - 不在原型上挂载可变状态或闭包变量,防止拷贝后行为错乱
上线前必须验证原型是否真被保留
光测字段值不够,要断言类型和方法可用性:
-
copy instanceof OriginalClass必须为true typeof copy.prototypeMethod === 'function'Object.getPrototypeOf(copy) === OriginalClass.prototype- 多层继承时,检查
Object.getPrototypeOf(Object.getPrototypeOf(copy))是否匹配预期
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











