JavaScript 的 class 是原型继承的语法糖,本质仍是函数和 prototype,不提供私有字段(除 #field)、不支持多重继承,static 方法与实例方法需通过类名或 this.constructor 调用,子类 constructor 必须首行调用 super()。

JavaScript 中 class 是语法糖,不是真正意义上的类
ES6 的 class 关键字只是对原型链继承的封装,背后仍是函数和 prototype。直接写 class A {} 等价于 function A() {},别被“类”字误导——它不提供私有字段(直到 #field 语法)、不支持多重继承、也不能像 Java 那样做编译期类型检查。
常见误解是以为 class 带来面向对象范式升级,其实只是让原型写法更可读。如果你在调试时发现 instanceof 行为异常或方法丢失,大概率是忘了 super() 或误用了箭头函数绑定。
定义 class 必须用 constructor,且子类继承必须调用 super()
没有显式 constructor,JS 会自动补一个空的;但一旦写了子类 constructor,就必须第一行调用 super(),否则报错 ReferenceError: Must call super constructor in derived class before accessing 'this'。
-
super()调用的是父类的constructor,传参要匹配父类签名 - 不能在
super()前访问this,包括this.xxx = y或console.log(this) - 如果父类构造器返回对象(罕见),
super()返回值会覆盖默认this
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // ✅ 必须第一行
this.breed = breed; // ✅ 此后才能用 this
}
}static 方法和实例方法不能互相调用 this,得靠类名或 super
static 方法里没有 this 指向实例,所以不能直接访问实例属性或调用实例方法;反过来,实例方法里用 this.constructor 可以拿到当前类(支持子类复用),但别硬写死类名——否则继承链一深就断。
立即学习“Java免费学习笔记(深入)”;
- 静态方法中想调用另一个静态方法:用
ClassName.method()或super.staticMethod()(仅限继承自父类) - 实例方法中想调用静态方法:用
this.constructor.staticMethod(),而不是this.staticMethod() - 避免在实例方法里写
Dog.doSomething(),换成this.constructor.doSomething()更健壮
class MathUtils {
static add(a, b) { return a + b; }
static multiply(a, b) { return a * b; }
}
class AdvancedMath extends MathUtils {
static calculate(x) {
return super.multiply(x, super.add(x, 1)); // ✅ 用 super 调父类 static
}
}extends 后面不只能跟 class,还能跟 null、函数甚至表达式
extends 实际上只要求右侧值有 prototype 属性(或为 null),所以你可以 extends null 创建无原型的对象,或 extends makeBaseClass() 动态生成父类。但绝大多数场景下,只建议继承真正的 class 或内置类(如 Error、Array)。
- 继承
Array时,子类实例不会被Array.isArray()认出,得靠Symbol.species修复 - 继承
Error时,V8 引擎要求必须调用super(message),否则堆栈信息丢失 - 不要
extends普通对象字面量(如{}),会报TypeError: Class extends value must be either undefined or null
真正难的从来不是写 class,而是理解什么时候不该用它——比如状态机、事件总线、纯函数工具集,强行套 class 只会让代码更难测试和重构。











