ES6 的 class 是基于原型的语法糖,不改变继承本质;必须用 class 关键字声明,类体中仅允许方法(含 constructor),属性需用类字段语法(如 age = 25)或 static 声明,私有字段以 # 开头,子类 constructor 中 super() 必须首行调用。

ES6 的 class 不是新引入的“类机制”,而是基于原型的语法糖,它不会改变 JavaScript 的继承本质。直接用 class 声明,比手写 function 构造函数 + prototype 更清晰,但若误以为它像 Java/C++ 那样有真正私有字段或静态类型,就容易踩坑。
如何正确定义一个 ES6 类
必须用 class 关键字声明,且类体中只能写方法(含 constructor),不能写属性赋值(除非用类字段语法,见下文)。
常见错误:在类体内直接写 name = 'foo'(不加 static 或未启用类字段提案)——这会报 SyntaxError: Unexpected token。
-
constructor是可选的,但若省略,系统会自动添加空构造器 - 所有方法默认不可枚举(
Object.keys()看不到),且自动绑定为非严格模式(但实际运行仍受全局严格模式影响) - 类声明不会被提升(
ReferenceError),必须先声明后使用
class Person {
constructor(name) {
this.name = name;
}
say() {
return `Hi, I'm ${this.name}`;
}
}类字段(Class Fields)怎么写才兼容
类字段(如 age = 25)属于 Stage 4 提案,现代浏览器和 Node.js 14+ 支持,但 TypeScript 编译或 Babel 处理时需确认目标环境。
立即学习“Java免费学习笔记(深入)”;
如果不经转译直接跑在旧环境(如 IE、Node.js 12),这类写法会直接报错,而非静默忽略。
- 实例字段写在类体内顶层,无需
constructor就能初始化:score = 0 - 静态字段用
static前缀:static defaultLevel = 'user' - 私有字段(
#id)也属同一提案,但目前仅 Chrome/Firefox/Node.js 14+ 支持,且无法被JSON.stringify序列化
class Counter {
count = 0; // 实例字段
static totalCount = 0; // 静态字段
#privateId = Math.random(); // 私有字段(注意 # 号)
}继承时 super() 必须调用的两种场景
子类定义了 constructor 就必须显式调用 super();另外,子类方法中访问 this 前,也必须确保 super() 已执行完毕 —— 否则会抛 ReferenceError: Must call super constructor。
- 如果子类没写
constructor,JS 会自动补一个constructor(...args) { super(...args); } -
super()必须在this之前调用,哪怕只是读this.constructor也不行 -
super.xxx可以在任何地方用(包括静态方法),但super()只能在实例构造器中用
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 必须第一句
this.breed = breed;
}
}静态方法和 getter/setter 的实际限制
static 方法不能访问 this(因为没有实例上下文),但它可以访问类自身和其他静态成员;而 get/set 本质上是定义在原型上的访问器属性,不是普通方法 —— 所以它们不能被 call/apply 动态调用,也不能被枚举(for...in 看不到)。
- 静态方法适合工具逻辑(如
Date.parse()),但别试图在其中操作实例状态 - getter/setter 内部用
this指向实例,但若在 setter 中修改同名属性(如set name(v) { this.name = v }),会无限递归 - 私有字段的 getter/setter 必须也用
#前缀,且不能混用公有与私有同名访问器
最易被忽略的一点:类内部的 async 方法、生成器方法(async foo() {} 或 *bar() {})都是合法的,但它们的语法支持依赖运行时 —— 比如 async 类方法在 Node.js 8+ 才可用,别想当然认为所有“看起来像类的地方”都支持。











