原型继承本身不危险,问题在于引用类型共享和初始化时机混淆;应在构造函数或类字段中初始化实例数据,避免原型上直接赋值引用类型,注意super()调用顺序、继承目标合法性及proxy代理时原型链完整性。

原型继承本身不危险,问题出在对引用类型共享机制的误用和初始化时机的混淆。关键不是绕开原型,而是让每个实例拥有独立数据副本。
别在原型上直接挂数组、对象或函数
这是最常踩的坑。一旦写成 Animal.prototype.items = [] 或 Component.prototype.config = {},所有实例就共用同一份内存。改一个,其他全跟着变——这不是 bug,是引用赋值的必然结果。
- 构造函数里初始化:每次
new都新建一份,安全可靠function User() { this.preferences = {}; this.tags = []; } - 类字段语法(推荐):自动绑定到实例,语义清晰
class Button { handlers = []; config = { disabled: false }; } - 用 getter 返回新对象:适合只读或需懒加载的场景
get defaults() { return { timeout: 3000, retries: 2 }; }
小心子类构造函数中 super() 的调用顺序
ES6 class 继承时,派生类构造函数必须先调用 super(),才能访问 this。否则会报 ReferenceError: Must call super constructor...。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不能省略
super(),哪怕父类没有显式构造函数 - 若需预处理参数,应在
super()之前完成,但不能碰this - 调用
super()后,this才被初始化,此时才能赋值或调用方法
避免继承 null 或非构造函数
虽然 class Foo extends null 语法合法,但会导致 Foo.prototype 的原型为 null,破坏标准原型链。实例无法访问 toString、hasOwnProperty 等基础方法。
- 不要让类继承
null、undefined或普通对象字面量 - 继承目标必须是具有
.prototype和可调用行为的函数 - 若需“无继承”结构,用
Object.create(null)创建干净对象,而非类继承
Proxy 代理类时注意原型链断裂
用 Proxy 包装构造函数时,若 construct 拦截器未正确传递 constructor 参数,新建实例的原型链会断开,导致 instanceof 失效、方法查找失败。
- 必须使用
Reflect.construct(target, args, constructor),第三个参数不能省 - 错误写法:
return new target(...args)—— 会丢失原型链 - 正确写法:
return Reflect.construct(target, args, constructor)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










