JavaScript中的Class类
在 JavaScript 中,类(Class)是 ES6(ECMAScript 2015)引入的核心特性,它提供了一种更清晰、更面向对象的方式来创建对象和处理继承。
基本语法
class Person {// 构造函数constructor(name, age) {this.name = name;this.age = age;}// 方法greet() {return `你好,我是${this.name},今年${this.age}岁。`;}// 静态方法static info() {return "这是一个Person类";}
}// 使用类
const alice = new Person("Alice", 30);
console.log(alice.greet()); // "你好,我是Alice,今年30岁。"
console.log(Person.info()); // "这是一个Person类"
核心概念
1. 构造函数(Constructor)
-
使用
constructor
方法定义 -
在创建类的新实例时自动调用
-
用于初始化对象属性
2. 方法(Methods)
-
类中定义的函数
-
自动添加到类的原型上
-
实例可以调用这些方法
3. 静态方法(Static Methods)
-
使用
static
关键字定义 -
只能通过类本身调用,不能通过实例调用
-
常用于工具函数或与类相关的操作
4. 继承(Inheritance)
-
使用
extends
关键字实现继承 -
子类可以通过
super
调用父类的构造函数和方法
class Student extends Person {constructor(name, age, grade) {super(name, age); // 调用父类的constructorthis.grade = grade;}study() {return `${this.name}正在学习${this.grade}年级的课程`;}// 重写父类方法greet() {return `${super.greet()} 我是一名${this.grade}年级的学生。`;}
}const bob = new Student("Bob", 15, 9);
console.log(bob.study()); // "Bob正在学习9年级的课程"
console.log(bob.greet()); // "你好,我是Bob,今年15岁。 我是一名9年级的学生。"
高级特性
1. Getter 和 Setter
class Rectangle {constructor(width, height) {this._width = width;this._height = height;}// Getterget area() {return this._width * this._height;}// Setterset width(value) {if (value > 0) {this._width = value;} else {console.log("宽度必须大于0");}}get width() {return this._width;}
}const rect = new Rectangle(10, 5);
console.log(rect.area); // 50 (使用getter)
rect.width = 15; // 使用setter
console.log(rect.area); // 75
2. 私有字段(ES2022+)
class BankAccount {// 私有字段(以#开头)#balance = 0;constructor(initialBalance) {this.#balance = initialBalance;}deposit(amount) {if (amount > 0) {this.#balance += amount;return `存款成功,当前余额:${this.#balance}`;}return "存款金额必须大于0";}withdraw(amount) {if (amount > 0 && amount <= this.#balance) {this.#balance -= amount;return `取款成功,当前余额:${this.#balance}`;}return "取款金额无效";}// 公共方法访问私有字段getBalance() {return this.#balance;}
}const account = new BankAccount(1000);
console.log(account.deposit(500)); // "存款成功,当前余额:1500"
console.log(account.withdraw(200)); // "取款成功,当前余额:1300"
console.log(account.getBalance()); // 1300
// console.log(account.#balance); // 错误:私有字段无法外部访问
3. 静态字段和静态块(ES2022+)
class Configuration {// 静态公共字段static apiUrl = "https://api.example.com";// 静态私有字段static #apiKey = "SECRET_KEY";// 静态初始化块static {// 可以执行复杂的静态初始化逻辑if (process.env.NODE_ENV === "development") {this.apiUrl = "https://dev-api.example.com";}}// 静态方法访问静态私有字段static getApiKey() {return this.#apiKey;}
}console.log(Configuration.apiUrl); // 根据环境不同
console.log(Configuration.getApiKey()); // "SECRET_KEY"
类与原型继承的关系
JavaScript 的类本质上是基于原型继承的语法糖:
// 类语法
class Person {constructor(name) {this.name = name;}greet() {return `Hello, ${this.name}!`;}
}// 等价的原型语法
function Person(name) {this.name = name;
}Person.prototype.greet = function() {return `Hello, ${this.name}!`;
};
类与普通函数的区别
特性 | 类 | 普通函数 |
---|---|---|
调用方式 | 必须使用 new 关键字 | 可以普通调用 |
提升 | 不会被提升 | 会被提升 |
严格模式 | 始终在严格模式下执行 | 取决于上下文 |
原型方法 | 在类体内定义 | 手动添加到原型 |
静态方法 | 使用 static 关键字 | 直接添加到构造函数 |
私有字段 | 支持(ES2022+) | 不支持 |
最佳实践
-
使用类代替构造函数:提供更清晰的语法结构
-
优先使用类字段语法:使属性初始化更直观
-
合理使用继承:保持继承层次简单(避免深层继承)
-
利用私有字段:封装内部实现细节
-
使用静态方法:对于不依赖实例的操作
-
考虑组合代替继承:对于复杂关系,使用组合可能更灵活
// 组合示例
class Logger {log(message) {console.log(`[LOG]: ${message}`);}
}class UserService {constructor(logger) {this.logger = logger;}register(user) {// 注册逻辑...this.logger.log(`用户 ${user.name} 注册成功`);}
}const logger = new Logger();
const userService = new UserService(logger);
userService.register({ name: "Alice" });
浏览器兼容性
JavaScript 类在现代浏览器中得到广泛支持:
-
Chrome 49+(2016年3月)
-
Firefox 45+(2016年3月)
-
Safari 10+(2016年9月)
-
Edge 13+(2016年)
-
Node.js 6.0+(2016年4月)
对于旧版浏览器,可以使用 Babel 等转译工具将类语法转换为 ES5 代码。
总结
JavaScript 的类提供了:
-
更清晰、更结构化的面向对象编程方式
-
简洁的继承语法(
extends
和super
) -
封装能力(私有字段和方法)
-
静态成员支持
-
Getter/Setter 访问器
虽然类本质上是基于原型的语法糖,但它们显著提高了代码的可读性和可维护性。在现代 JavaScript 开发中,类已成为创建复杂对象和组织代码结构的标准方式。