重写 prototype 必然断链:赋值操作使 child.prototype.__proto__ 从 parent.prototype 变为 object.prototype,导致新实例无法访问父类方法、instanceof 失败、constructor 指向 object;应通过 object.assign 或 object.create(parent.prototype) 安全扩展。

重写 prototype 会直接切断子类与父类之间的原型链连接,导致继承关系失效。这不是“可能出问题”,而是必然发生——只要用赋值方式覆盖整个 prototype 对象,原有链路就断了。
为什么重写 prototype 会断链
构造函数的 prototype 是实例的 [[Prototype]] 查找起点。一旦执行类似 Child.prototype = {} 或 Child.prototype = new Parent() 这样的赋值操作,就等于把原来指向 Parent.prototype 的那条链替换成一个全新对象。这个新对象的 [[Prototype]] 默认是 Object.prototype,不再连向父类原型。
-
Child.prototype.__proto__原本应为Parent.prototype,重写后变成Object.prototype - 所有已创建的
Child实例仍保留旧的__proto__指向(即旧Child.prototype),但新实例将使用新的prototype,造成不一致 - 父类方法(如
sayName)在新实例上彻底不可访问,instanceof判断也会失败
constructor 指向丢失是断链的明显信号
重写 prototype 后,新对象没有 constructor 属性,引擎会沿原型链向上找,最终落到 Object.prototype.constructor,于是 new Child().constructor === Object。这说明查找已经越过父类原型,落在了顶层。
- 不是 bug,而是链路被重定向后的自然结果
-
Child.prototype.constructor = Child只是补回属性,不能恢复原型链本身 - 真正要修复的是
Child.prototype.__proto__的指向,而非仅 constructor
如何安全地扩展 prototype 而不断链
避免整体替换,改用增量更新方式保持原有原型链结构:
- 用
Object.assign(Child.prototype, { method() {} })添加方法,不改变__proto__ - 若必须新建原型对象,用
Object.create(Parent.prototype)构造,确保__proto__正确指向父类原型 - 之后再手动设置
constructor:Object.defineProperty(Child.prototype, 'constructor', { value: Child, writable: true, enumerable: false }) - 对关键原型调用
Object.freeze(Child.prototype),防止后续意外覆盖
断链后怎么确认和验证
不要只看 constructor,要用原生 API 确认实际链路:
-
Object.getPrototypeOf(new Child())→ 应返回Child.prototype -
Object.getPrototypeOf(Child.prototype)→ 断链时返回Object.prototype,正常时应为Parent.prototype -
new Child() instanceof Parent→ 断链后为false - 调用父类方法:
new Child().sayName()报TypeError: not a function即链已断
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











