JavaScript继承中,实例属性须在构造函数中用this初始化以保障独立性,方法应统一放在原型上实现复用;推荐ES6 class语法,其天然规避重复调用父构造函数问题,兼顾安全与性能。

JavaScript 继承中,属性初始化方式直接影响实例独立性、内存占用和运行时性能。关键不在于“用哪种继承”,而在于明确区分:哪些属性该在实例上初始化(保障隔离),哪些方法该在原型上共享(保障复用)。
实例属性必须在构造函数中初始化
父类中的引用类型属性(如数组、对象、函数)若直接定义在 prototype 上,所有子类实例会共享同一份数据,造成意外修改。正确做法是:在父类和子类的构造函数中,用 this 显式赋值。
- 父类构造函数负责初始化自身专属实例属性(
this.name、this.colors = []) - 子类构造函数必须调用 super()(ES6 class)或 Parent.call(this, ...)(ES5),把参数传给父类完成初始化
- 子类独有的属性(如
this.breed或this.grade)也在自己的构造函数中设置
方法应统一放在原型上复用
把方法写在构造函数内部会导致每个实例都生成一份副本,浪费内存;而放在 prototype 或 class 的类体中(非 constructor 内),可被所有实例共享,显著节省空间。
- ES6 class 中,所有非静态、非构造器的方法默认定义在原型上
- ES5 中,应将共用方法挂到
Parent.prototype,再通过Object.create(Parent.prototype)建立子类原型链 - 避免在构造函数里重复定义方法,例如不要写
this.sayName = function() {...}
避免组合继承里的父类构造函数重复执行
经典组合继承会两次调用父类构造函数:一次在子类构造函数内(Parent.call(this)),另一次在设置原型时(Child.prototype = new Parent())。后者仅为了获取原型方法,却无谓地执行了父类初始化逻辑,还可能引发副作用。
立即学习“Java免费学习笔记(深入)”;
- 推荐使用寄生组合继承:用
Object.create(Parent.prototype)创建干净原型对象,跳过执行父类构造函数 - 手动修正
constructor指向:Child.prototype.constructor = Child - 现代项目中,直接使用
class Child extends Parent即可自动规避该问题
ES6 class 是当前最平衡的实践方案
它天然融合了安全初始化与高效复用:构造函数强制调用 super() 保证属性初始化顺序,方法自动挂载原型,语法简洁且语义清晰。
- 子类 constructor 中必须第一行调用
super(...),否则报错 - 父类未定义 constructor 时,子类
super()仍会调用默认空构造函数,安全无副作用 - 静态方法和属性也支持继承,但不会出现在实例上,适合工具型扩展



















