解构运算符无法保留原型链,它仅创建继承自Object.prototype的普通对象;需用构造函数重建实例或structuredClone实现原型安全拷贝。

解构运算符({...obj})本身无法传递或复原原型链,它只创建一个继承自 Object.prototype 的新普通对象,原构造函数、类方法、instanceof 判断全部丢失。这不是“没做好”,而是设计如此——解构本质是属性提取+对象字面量重建,不涉及原型操作。
为什么解构做不到保留原型
解构语法等价于:const copy = {}; Object.assign(copy, obj);
而 Object.assign 和展开运算符都只复制可枚举的自有属性,完全忽略:
- 原型上的方法和属性
- 不可枚举属性(如 Object.prototype.toString)
- Symbol 键
- 构造函数信息和继承关系
想保留原型,得绕过解构,换用构造器重建
如果目标对象是某个类的实例(比如 class User { ... }),且你确实需要拷贝后仍能调用原型方法、通过 instanceof User 判断,那就不能依赖解构。正确做法是:
- 用原构造函数创建新实例:
const copy = new obj.constructor(...) - 再把源对象的自有属性逐个赋值过去(可用
Object.assign或for...in+hasOwnProperty) - 注意:前提是
constructor可安全调用,且不依赖内部私有状态(如闭包变量、WeakMap缓存)
多数场景下,其实不需要原型链
日常开发中,90% 的“拷贝”需求只是为了隔离数据修改,而非复用类行为。例如表单状态、配置对象、API响应数据——这些本就是纯数据容器。此时解构完全够用,还更轻量、更安全:
- 不会意外触发构造函数副作用
- 不暴露内部实现细节(如私有字段、Symbol 属性)
- 避免因原型方法访问
this导致上下文错误
真要深拷贝+保原型?用现代标准 API
如果既要完整克隆嵌套结构,又要尽量保留类型信息(如 Date、Map、RegExp),推荐使用:
-
structuredClone(obj):浏览器原生支持(Chrome 98+/Firefox 94+/Safari 16.4+),能正确处理大多数内置类型,但不支持函数和 DOM 节点 - 搭配
Object.setPrototypeOf(copy, Object.getPrototypeOf(obj))可手动补原型(仅限普通对象,对 Date/Map 等无效) - 老环境兜底:Lodash 的
cloneDeep更全面,但需引入库

















