JavaScript类继承需在子类构造函数首行调用super(),否则报错;super()必须在访问this前执行;可调用父类方法、静态成员;继承内置类需额外处理以确保行为正确。

JavaScript 的 Class 继承用 extends + super() 实现,但必须注意构造函数中调用 super() 的时机和必要性,否则会直接报错。
子类构造函数里必须显式调用 super()
ES6 的 class 继承不是“自动完成”的。如果子类定义了 constructor,就必须在第一行调用 super(),否则会抛出 ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor。
-
super()必须在访问this之前调用(包括给this.xxx赋值、调用this.method()) - 如果子类没写
constructor,JS 引擎会自动插入一个空的constructor(...args) { super(...args); } - 传给
super()的参数,就是父类构造函数期望接收的参数
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // ✅ 必须先调用
this.breed = breed; // ✅ 此时 this 才可用
}
}
super 不只是调用父构造函数,还能访问父类方法和属性
super 在子类实例方法中不是关键字,而是一个特殊的引用对象,可用来调用父类的同名方法(包括 constructor),也能读取父类的 get 访问器或原型上的属性。
- 在方法内部用
super.xxx()调用父类方法(如super.toString()) - 不能在静态方法里用
super()调构造函数,但可以用super.xxx访问父类静态属性或方法 -
super指向的是父类的prototype,不是父类实例
class Animal {
speak() { return `I'm ${this.name}`; }
}
class Dog extends Animal {
speak() {
return super.speak() + ' — woof!'; // ✅ 复用父逻辑
}
}
静态方法和静态属性的继承规则容易被忽略
子类会继承父类的静态方法(通过 Class.staticMethod),但不会自动继承静态属性(ES2022+ 支持公有静态字段,但不会被子类“继承”为自有属性)。
立即学习“Java免费学习笔记(深入)”;
- 静态方法可通过
super.staticMethod()在子类静态方法中调用 - 父类的
static get xxx() {}可被子类通过super.xxx访问 - 子类若未定义同名静态字段,访问
Child.staticProp会沿原型链找到父类定义(仅限 getter/setter 或方法;普通静态字段不参与原型链查找)
class Animal {
static kingdom = 'Animalia';
static info() { return 'A living organism'; }
}
class Dog extends Animal {}
console.log(Dog.kingdom); // ✅ 'Animalia'(仅当父类用 getter 或是旧式赋值时才可读)
console.log(Dog.info()); // ✅ 'A living organism'
继承内置类(如 Array、Error)需要额外小心
继承 Array、Map、Error 等内置类时,仅靠 extends 和 super() 不足以让实例具备完整行为(比如 Array 子类实例可能没有 .length 自动更新或 for...of 支持)。
- V8(Chrome/Node.js)对内置类继承支持较好,但 Safari 和部分旧环境仍有缺陷
- 继承
Error时,需手动设置this.name和this.message,否则instanceof可能失效 - 推荐优先使用组合(composition)替代继承内置类,除非明确需要 instanceof 行为
class MyError extends Error {
constructor(message) {
super(message);
this.name = 'MyError'; // ✅ 必须补上,否则 .name 是 'Error'
// 还建议加:Object.setPrototypeOf(this, MyError.prototype);
}
}
真正麻烦的不是语法,而是 super() 的调用约束、静态成员的查找规则,以及内置类继承在不同引擎下的行为差异——这些地方一旦出错,错误信息往往不直观,调试成本远高于普通逻辑问题。











