JavaScript类(class)

JavaScript类(Class)知识点详解

JavaScript类(Class)核心知识点

编程小白也能理解的JavaScript类(class)详解

面向对象

类是实现面向对象编程(OOP)的基础

代码复用

通过类实现代码复用和组织

继承机制

使用extends实现类之间的继承

类的基本概念

类(Class)是创建对象的模板,它定义了对象的属性和方法。

想象类就像建筑蓝图,而对象是按照蓝图建造的实际房屋。

class Person { // 定义一个Person类
  constructor(name, age) { // 构造方法
    this.name = name; // 实例属性
    this.age = age;
  }

  introduce() { // 实例方法
    return `大家好,我是${this.name},今年${this.age}岁。`;
  }
}

温馨提示: JavaScript中的类本质上是基于原型的继承的语法糖,提供了更清晰、更面向对象的写法。

构造函数

constructor 是类的特殊方法,在创建类的新实例时自动调用。

它主要用于初始化对象的属性,每个类只能有一个构造函数。

class Car {
  constructor(brand, year) {
    this.brand = brand;
    this.year = year;
    this.isNew = year >= 2020;
  }
}

// 创建实例
const myCar = new Car(‘Toyota’, 2022);

使用 new 关键字创建类的实例:

  1. 创建一个新的空对象
  2. 将新对象的原型指向类的原型
  3. 执行构造函数,并将新对象绑定到this
  4. 返回新创建的对象

方法与属性

实例方法

在类中定义的方法会被添加到类的原型(prototype)中,所有实例共享这些方法。

class Circle {
  constructor(radius) {
    this.radius = radius;
  }

  area() { // 实例方法
    return Math.PI * this.radius ** 2;
  }
}

静态方法

使用 static 关键字定义,属于类本身而不是实例。

class MathUtils {
  static square(x) { // 静态方法
    return x * x;
  }
}

// 调用静态方法
MathUtils.square(5); // 25

继承

使用 extends 关键字实现类之间的继承。

子类可以继承父类的属性和方法,也可以添加自己的属性和方法。

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} 发出声音。`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // 调用父类构造函数
    this.breed = breed;
  }

  speak() { // 方法重写
    console.log(`${this.name} 汪汪叫!`);
  }
}

super关键字: 用于调用父类的构造函数或方法。在子类构造函数中,super必须在this之前调用。

Getter与Setter

用于定义获取和设置属性值的特殊方法,提供对属性访问的控制。

class Temperature {
  constructor(celsius) {
    this._celsius = celsius; // 约定用下划线表示内部属性
  }

  get celsius() { // getter
    return this._celsius;
  }

  set celsius(value) { // setter
    if (value < -273.15) {
      console.log(“温度不能低于绝对零度!”);
      return;
    }
    this._celsius = value;
  }

  get fahrenheit() { // 计算属性
    return this._celsius * 9/5 + 32;
  }
}

使用getter/setter的好处:

  • 验证数据
  • 计算属性
  • 封装内部实现
  • 提供更友好的API

私有字段与方法

在类中,可以使用 # 前缀来定义私有字段和私有方法。

私有成员只能在类的内部访问,外部无法直接访问。

class BankAccount {
  #balance = 0; // 私有字段

  deposit(amount) {
    if (amount > 0) {
      this.#balance += amount;
    }
  }

  withdraw(amount) {
    if (amount > 0 && amount <= this.#balance) {
      this.#balance -= amount;
      return amount;
    }
    return 0;
  }

  #logTransaction(type, amount) { // 私有方法
    console.log(`${type} ${amount}元`);
  }

  get balance() {
    return this.#balance;
  }
}

注意: 私有字段是ES2022的新特性,在不支持的环境中可能需要转译器(如Babel)来处理。

类的实用技巧

封装与抽象

类可以把数据和操作数据的方法封装在一起,对外只暴露必要的接口。

多态性

子类可以重写父类的方法,实现不同的行为。

class Shape {
  area() { // 抽象方法(在JS中并没有真正的抽象方法)
    throw new Error(‘子类必须实现area方法’);
  }
}

class Square extends Shape {
  constructor(side) {
    super();
    this.side = side;
  }

  area() { // 实现多态
    return this.side ** 2;
  }
}

class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  area() { // 实现多态
    return Math.PI * this.radius ** 2;
  }
}

类的扩展

可以给现有的类添加新方法(但通常不建议修改内置类的原型)

// 给Array类添加一个新方法
class MyArray extends Array {
  last() {
    return this[this.length – 1];
  }
}

const arr = new MyArray(1, 2, 3);
console.log(arr.last()); // 3

类的优势

  • 代码组织结构更清晰
  • 提高代码复用性
  • 实现封装和信息隐藏
  • 支持继承和多态

注意事项

  • 类定义不会被提升(必须先定义后使用)
  • 类中的方法不需要function关键字
  • 类的方法之间不需要逗号分隔
  • 类本质仍然是函数和原型继承

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部