原型继承中引用类型属性共享是机制正常运行结果,解决方法包括:1.构造函数内初始化;2.类字段语法;3.子类调用父类构造函数;4.getter返回新对象。

原型继承中引用类型属性共享,本质不是 bug,而是原型链机制按规则运行的结果:所有实例共用同一份 prototype 上的引用值。解决的关键,是让每个实例拥有自己的引用副本,而不是共用“模板”。
构造函数内初始化引用属性
每次 new 实例时,构造函数都会重新执行,自然为每个实例生成独立的引用。
- 适用于传统 function 构造函数写法
- 把原本写在 prototype 上或父类实例中的引用属性(如 arr = []、config = {}),移到构造函数体内初始化
- 示例:function Person() { this.tags = []; this.meta = {}; }
使用类字段语法(推荐)
ES6+ 类语法中,类字段直接绑定到实例,语义清晰且自动隔离。
- 避免手动调用构造逻辑,也无需担心 prototype 污染
- 字段声明即初始化,每个实例独享一份
- 示例:class Button { handlers = []; settings = { size: 'm' }; }
子类继承时必须调用父类构造函数
仅靠 Child.prototype = Object.create(Parent.prototype) 只能继承方法;若要继承并隔离实例属性,需在子构造函数中显式调用 Parent.call(this)。
- 确保父类中定义的引用属性(如 this.items = [])被复制到当前子实例上
- 不能省略 Object.create(Parent.prototype),否则无法访问父类原型方法
- 错误写法:Child.prototype = new Parent() —— 会让所有子实例共享父类一次执行产生的引用
用 getter 返回新对象(适合默认配置)
对不常修改、仅作默认值使用的引用类型,可通过 getter 每次返回新实例。
- 延迟创建,节省内存;且彻底隔绝副作用
- 不适合频繁读写的业务状态,仅推荐用于配置、模板等只读场景
- 示例:get defaults() { return { timeout: 3000, retries: 2 }; }
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











