安全继承需避免修改父类原型,应在子类原型上操作;用Object.create(Parent.prototype)创建独立原型,重写时显式调用Parent.prototype.method.call(this)或super.method();可冻结Parent.prototype防误改;优先用私有字段和封装替代原型暴露。

直接修改父级原型(比如 Parent.prototype.method = ...)会影响所有已存在和将创建的实例,包括子类实例,造成不可控的全局副作用。真正安全的做法是**不碰父类原型本身,只在子类自己的原型对象上定义或重写**,同时确保继承链干净、状态隔离。
只在子类原型上操作,不污染 Parent.prototype
父类原型是共享的“模板”,任何对其的增删改都会波及整个继承体系。正确做法是让子类拥有独立的原型对象,并仅在此对象上添加或覆盖方法:
- 用
Object.create(Parent.prototype)创建新原型对象,它复用父类方法但不绑定父类初始化逻辑 - 所有子类特有逻辑(包括重写的方法)都赋值到这个新对象上,例如:
Child.prototype.say = function() { ... } - 绝对避免
Parent.prototype.say = ...这类直接赋值,哪怕只是“临时调试”也不建议
重写方法时保留对父逻辑的可控调用
覆盖不是抛弃——多数场景下需要在子类方法中执行父类原有逻辑,再扩展。这时应显式调用,而非依赖原型链自动查找:
- 使用
Parent.prototype.method.call(this, ...)精确调用父类版本,避免因原型被意外修改导致行为漂移 - 若用
class语法,统一通过super.method()调用,语义清晰且受语法约束 - 不要在子类方法里写
this.constructor.prototype.method()—— 构造函数可能被替换,不可靠
冻结父类原型,从运行时层面设防
对已发布的父类,可主动冻结其原型,防止后续误改(尤其在大型项目或第三方库集成时):
立即学习“Java免费学习笔记(深入)”;
- 在父类定义完成后立即执行:
Object.freeze(Parent.prototype) - 冻结后,尝试给
Parent.prototype.xxx = ...赋值会静默失败(严格模式下抛错) - 注意:冻结只作用于该对象自身属性,不影响原型链上更上层的可写性
用私有字段和封装边界替代原型暴露
很多“想改父类原型”的需求,本质是父类设计过度暴露。更健壮的解法是从源头减少可修改面:
- 把核心逻辑收进私有方法(
#validate())或闭包内,子类无法访问或覆盖 - 对外只提供带守卫的公有方法,例如
save()内部强制先调用#doCoreSave() - 关键数据状态全部放在实例上(
this.#cache = new Map()),不放原型,避免共享与误改


















