JavaScript 类(class)
关键要点
- JavaScript 类是创建对象的模板,基于原型,语法简洁。
- 类有构造函数、方法、字段,可通过
extends
实现继承。 - 私有属性用
#
符号,静态方法用static
关键字。 - 类始终在严格模式下,
this
绑定与普通函数不同。
定义与使用
JavaScript 类用 class
关键字定义,包含构造函数和方法。例如:
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
return `Hello, ${this.name}`;
}
}
const p = new Person("Alice");
console.log(p.sayHello()); // 输出 "Hello, Alice"
类支持继承,如 class Student extends Person
,子类需用 super()
调用父类构造函数。
私有与静态
私有属性用 #
定义,仅类内访问;静态方法用 static
定义,属于类而非实例。例如:
class MyClass {
#privateField = "secret";
static staticMethod() {
return "Static method called";
}
}
注意事项
类在严格模式下运行,this
绑定需注意上下文。类声明受时间死区影响,必须先定义后使用。
详细报告
JavaScript 类(class)是 ECMAScript 2015(ES6)引入的语法糖,旨在提供更直观的面向对象编程方式。尽管 JavaScript 底层仍是基于原型的,但类提供了更接近传统面向对象语言(如 Java、C++)的语法。以下是关于 JavaScript 类的全面中文讲解。
什么是类?
类是创建对象的模板,用于封装数据和处理这些数据的方法。类基于原型(prototype)继承,但有独特的语法和语义。自 2016 年 3 月起,类成为 JavaScript 标准的一部分,浏览器支持度较高。
- 特点:类是函数的语法糖,实际上仍是构造函数,但提供了更清晰的结构。
- 用途:适合定义对象模板,管理状态和行为,如用户、商品等。
定义类的两种方式
有两种定义类的方式:
- 类声明(Class Declaration):
class MyClass {
// 类体
}
类声明必须在定义前使用,受时间死区(Temporal Dead Zone, TDZ)限制。
- 类表达式(Class Expression):
const MyClass = class {
// 类体
};
类表达式可以匿名或命名,灵活性更高。
类体的组成
类体用大括号 {}
包裹,包含以下元素:
- 构造函数(Constructor):用于创建和初始化对象。每个类最多有一个构造函数,否则抛出 SyntaxError。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
- 方法(Methods):定义在原型上,实例共享。支持普通函数、异步函数(
async
)、生成器函数(function*
)和异步生成器函数。
class MyClass {
myMethod() {
return "Regular method";
}
async asyncMethod() {
return await Promise.resolve("Async method");
}
}
- 静态方法和字段(Static Methods and Fields):用
static
关键字定义,属于类本身而非实例,适合工具函数或固定数据。
class MathUtil {
static add(a, b) {
return a + b;
}
}
console.log(MathUtil.add(5, 3)); // 输出 8
- 字段声明(Field Declaration):在类体中直接定义属性,可有默认值或为
undefined
。这是 ES2022 引入的特性。
class MyClass {
myField = "default";
anotherField; // 默认 undefined
}
- 私有属性(Private Properties):用
#
符号声明,仅类内部可访问,提供封装性。
class MyClass {
#privateField = "secret";
getPrivate() {
return this.#privateField;
}
}
const obj = new MyClass();
console.log(obj.getPrivate()); // 输出 "secret"
console.log(obj.#privateField); // 错误:私有字段不可访问
继承与 extends
类支持继承,使用 extends
关键字。子类构造函数必须先调用 super()
,以确保父类初始化完成。
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound`;
}
}
class Dog extends Animal {
constructor(name) {
super(name); // 调用父类构造函数
}
speak() {
return `${this.name} barks`;
}
}
const dog = new Dog("Rex");
console.log(dog.speak()); // 输出 "Rex barks"
类评估顺序
类的评估顺序包括以下步骤:
- 评估
extends
子句(如果有)。 - 评估构造函数。
- 评估属性键。
- 设置方法和存取器。
- 初始化字段和静态属性。
- 类准备好作为构造函数使用。
如果在类定义前访问类名,会抛出 ReferenceError。
this
的绑定
类始终在严格模式下运行,this
的绑定与普通函数不同:
- 在方法调用时,如果没有明确上下文,
this
为undefined
,而非全局对象(如window
)。 - 示例:
class MyClass {
method() {
console.log(this);
}
}
const obj = new MyClass();
obj.method(); // 输出实例对象
MyClass.method(); // 严格模式下抛错,this 为 undefined
最佳实践与注意事项
- 严格模式:类始终在严格模式下运行,需注意
this
绑定和变量声明。 - 时间死区:类声明和表达式受 TDZ 影响,必须先定义后使用。
- 私有属性:使用
#
确保封装,避免外部直接访问。 - 静态初始化块:ES2022 引入,支持灵活初始化静态属性。
class MyClass {
static {
this.staticField = "Initialized";
}
}
表格:类元素总结
元素 | 描述 | 示例 |
---|---|---|
构造函数 | 初始化对象,子类需用 super() 调用父类 | constructor(name) { this.name = name; } |
普通方法 | 原型方法,实例共享 | sayHello() { return "Hello"; } |
静态方法 | 属于类,实例不可访问 | static add(a, b) { return a + b; } |
字段 | 类体中定义属性,可有默认值 | myField = "default"; |
私有属性 | 用 # 声明,仅类内访问 | #privateField = "secret"; |
继承 | 用 extends 实现,子类需调用 super() | class Child extends Parent { ... } |
总结
JavaScript 类提供了一种现代化的面向对象编程方式,支持构造函数、方法、字段、继承和私有属性。类基于原型,但语法更直观,适合构建复杂对象结构。需注意严格模式和时间死区的限制,使用时遵循最佳实践以提高代码可维护性。