避免对象合并时继承层级丢失,关键在于不替换prototype而只扩展它,禁用object.assign直接覆盖prototype,改用object.assign(myclass.prototype, ...)或object.setprototypeof,并确保constructor正确指向。

避免对象合并时继承层级意外丢失,核心是别让 Object.assign 或展开运算符直接覆盖原型对象,尤其不能用它们去重写构造函数的 prototype。
别用 Object.assign 覆盖整个 prototype
这是最常见出错点。比如:
MyClass.prototype = Object.assign({}, Parent.prototype, { method() {} });
这样生成的新对象没有 constructor,且原型链顶端变成 Object.prototype,导致 instance.constructor 指向 Object,instance instanceof MyClass 也可能失效。
- 正确做法:只扩展已有 prototype,不替换它
Object.assign(MyClass.prototype, Parent.prototype, { method() {} });- 或用
Object.setPrototypeOf显式设置原型关系(适合动态场景)
合并前先确认目标对象是否带原型
如果合并目标本身是普通字面量(如 {}),它默认原型是 Object.prototype;若你希望它继承自某个类,得手动指定:
- 用
Object.create(DesiredPrototype)创建带指定原型的空对象再合并 - 例如:
const target = Object.create(MyClass.prototype); Object.assign(target, data); - 避免直接
const target = {...data}—— 展开后原型固定为Object.prototype
警惕 Proxy 和 Reflect.construct 的组合陷阱
当被合并的对象来自 Proxy 包裹的类实例,且 construct 拦截器没传 new.target,新对象的原型链会断在 Object.prototype 或 null,后续合并无法恢复继承关系。
- 检查实例原型:
Object.getPrototypeOf(instance) === ExpectedClass.prototype - 修复需两步:先
Object.setPrototypeOf(instance, ExpectedClass.prototype) - 再确保
ExpectedClass.prototype.constructor === ExpectedClass
需要深合并时,别依赖原生方法
Object.assign 和展开运算符都只浅拷贝,对嵌套对象、数组、函数等引用类型不做隔离,容易引发共享问题,间接破坏继承语义(比如多个实例共用一个 config 对象)。
- 若必须深合并,用专门库(如 lodash 的
merge)或手写逻辑,确保每个层级新建对象 - 对配置类数据,推荐用 getter 返回新副本:
get options() { return { ...this._defaults }; } - 避免在原型上存可变引用(如
prototype.cache = {})











