什么是 class 语法?
JavaScript 本质是基于原型的语言,但 ES6 引入了 class 关键字,提供了一种更直观的面向对象编程(OOP)语法。class 不是新的继承模型,而是原型继承的语法,让代码更易读和结构化。
基础语法
1. 定义类
class Person {// 构造函数constructor(name, age) {this.name = name;this.age = age;}// 方法(自动绑定到原型)greet() {console.log(`Hello, I'm ${this.name}!`);}}// 使用类const alice = new Person("Alice", 30);alice.greet(); // "Hello, I'm Alice!"
对比传统写法
// ES5 等效代码function Person(name, age) {this.name = name;this.age = age;}Person.prototype.greet = function() {console.log("Hello, I'm " + this.name + "!");};
核心特性
1. 继承(extends + super)
class Student extends Person {constructor(name, age, grade) {super(name, age); // 调用父类构造函数this.grade = grade;}study() {console.log(`${this.name} is studying in grade ${this.grade}.`);}// 重写父类方法greet() {super.greet(); // 调用父类方法console.log("I'm a student!");}}const bob = new Student("Bob", 18, 12);bob.greet();// "Hello, I'm Bob!"// "I'm a student!"bob.study(); // "Bob is studying in grade 12."
2. 静态方法(static)
class MathUtils {static add(a, b) {return a + b;}}console.log(MathUtils.add(2, 3)); // 5// 无需实例化即可调用
3. Getter/Setter
class Circle {constructor(radius) {this._radius = radius;}get area() {return Math.PI * this._radius ** 2;}set radius(value) {if (value <= 0) throw new Error("Radius must be positive");this._radius = value;}}const circle = new Circle(5);console.log(circle.area); // 78.54...circle.radius = 10; // 调用 setter
4. 私有字段(ES2022+)
class Wallet {#balance = 0; // 私有字段(以 # 开头)deposit(amount) {this.#balance += amount;}getBalance() {return this.#balance;}}const wallet = new Wallet();wallet.deposit(100);console.log(wallet.getBalance()); // 100// console.log(wallet.#balance); // 报错:私有字段不可访问
注意事项
1. 没有函数提升
const p = new Person(); // 报错!类必须先声明后使用class Person {}
2. 方法不可枚举
类方法默认不可枚举(Object.keys() 不会列出)。
3. 必须使用 new 调用
const p = Person(); // 报错!类必须通过 new 实例化
4. 箭头函数与 this 绑定
class Button {constructor() {this.clickCount = 0;// 使用箭头函数自动绑定 thisthis.handleClick = () => {this.clickCount++;};}}
高级技巧
1. Mixin 模式
// 定义可复用的功能块const Loggable = (Base) => class extends Base {log(message) {console.log(`[${this.constructor.name}] ${message}`);}};class User extends Loggable(Person) {constructor(name) {super(name);}}const user = new User("Charlie");user.log("Created"); // "[User] Created"
2. 动态类名
const className = "Animal";const Animal = class {// ...};const Dog = class extends Animal {// ...};
3. 自引用技巧
注意class LinkedListNode {constructor(value) {this.value = value;this.next = null;}append(value) {this.next = new LinkedListNode(value);return this.next;}}const head = new LinkedListNode(1);head.append(2).append(3);
-
优先使用 class
在需要明确对象结构和继承时,替代function + prototype。 -
避免滥用继承
组合优先于继承(使用 Mixin 或模块)。 -
私有字段保护数据
使用#实现真正私有(代替_前缀约定)。 -
统一代码风格
方法间不留空行,保持紧凑的类结构。
![]() |
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |




浙公网安备 33010602011771号