关于JavaScript类(class)及TypeScript对类扩展的关键字整理

240 阅读3分钟

在 JavaScript 中,类(class)有几个关键字和概念,每个都有其特定的含义和作用。以下是主要的关键字及其用途:

1. class

class 关键字用于定义一个类。类是创建对象的模板,可以包含构造函数、方法和属性。

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        return `Hello, my name is ${this.name}`;
    }
}

const person = new Person('Alice', 30);
console.log(person.greet()); // 输出: Hello, my name is Alice

2. constructor

constructor 是一个特殊的方法,用于初始化类的实例。每个类只能有一个构造函数。

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

const animal = new Animal('Dog');
console.log(animal.type); // 输出: Dog

3. super

super 关键字用于调用父类的构造函数和方法。它必须在子类的构造函数中调用,以确保父类的构造函数被正确执行。

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

class Child extends Parent {
    constructor(name, age) {
        super(name); // 调用父类的构造函数
        this.age = age;
    }
}

const child = new Child('Bob', 5);
console.log(child.name); // 输出: Bob
console.log(child.age);  // 输出: 5

4. extends

extends 关键字用于创建一个类,该类是另一个类的子类。子类继承父类的所有方法和属性。

class Vehicle {
    constructor(make) {
        this.make = make;
    }
}

class Car extends Vehicle {
    constructor(make, model) {
        super(make);
        this.model = model;
    }
}

const car = new Car('Toyota', 'Corolla');
console.log(car.make);  // 输出: Toyota
console.log(car.model); // 输出: Corolla

5. static

static 关键字用于定义类的静态方法或属性。静态方法和属性不属于类的实例,而是直接属于类本身。

class MathUtil {
    static add(a, b) {
        return a + b;
    }
}

console.log(MathUtil.add(2, 3)); // 输出: 5

6. get 和 set

get 和 set 关键字用于定义对象的属性访问器。get 用于获取属性的值,set 用于设置属性的值。

class Rectangle {
    constructor(width, height) {
        this.width = width;
        this.height = height;
    }

    get area() {
        return this.width * this.height;
    }

    set area(value) {
        this.width = Math.sqrt(value);
        this.height = Math.sqrt(value);
    }
}

const rect = new Rectangle(4, 5);
console.log(rect.area); // 输出: 20
rect.area = 16;
console.log(rect.width);  // 输出: 4
console.log(rect.height); // 输出: 4

7. abstract

abstract 关键字用于定义抽象类和抽象方法。抽象类不能被实例化,只能被继承。抽象方法必须在子类中实现。

abstract class Animal {
    abstract makeSound(): void; // 抽象方法,没有方法体

    move(): void {
        console.log("Moving...");
    }
}

class Dog extends Animal {
    makeSound(): void {
        console.log("Bark");
    }
}

const dog = new Dog();
dog.makeSound(); // 输出: Bark
dog.move();      // 输出: Moving...

8. private

private 关键字用于定义私有成员,这些成员只能在类的内部访问,不能在类的外部或子类中访问。

class Person {
    private name: string;

    constructor(name: string) {
        this.name = name;
    }

    getName(): string {
        return this.name;
    }
}

const person = new Person("Alice");
console.log(person.getName()); // 输出: Alice
console.log(person.name);      // 错误: Property 'name' is private and only accessible within class 'Person'.

9. protected

protected 关键字用于定义受保护的成员,这些成员只能在类的内部和子类中访问,不能在类的外部访问。

class Vehicle {
    protected brand: string;

    constructor(brand: string) {
        this.brand = brand;
    }
}

class Car extends Vehicle {
    constructor(brand: string) {
        super(brand);
    }

    getBrand(): string {
        return this.brand;
    }
}

const car = new Car("Toyota");
console.log(car.getBrand()); // 输出: Toyota
console.log(car.brand);      // 错误: Property 'brand' is protected and only accessible within class 'Vehicle' and its subclasses.

10. implements

implements 关键字用于让一个类实现一个或多个接口。接口定义了类必须实现的方法和属性,但不提供具体实现。通过实现接口,类可以确保遵循特定的结构和行为。

使用 implements 的基本步骤:

  1. 定义接口:接口中声明方法和属性,但不提供具体实现。
  2. 实现接口:使用 implements 关键字让一个类实现接口,并提供接口中所有方法和属性的具体实现。
// 定义接口
interface Animal {
    makeSound(): void;
    sleep(): void;
}

// 实现接口
class Dog implements Animal {
    makeSound(): void {
        console.log("Woof");
    }

    sleep(): void {
        console.log("Zzz");
    }
}

// 使用实现类
const myDog = new Dog();
myDog.makeSound(); // 输出: Woof
myDog.sleep();     // 输出: Zzz

注意事项:

  • 一个类可以实现多个接口,用逗号分隔。
  • 实现接口时,必须实现接口中的所有方法和属性。
  • 接口中的方法默认是 public

多重实现示例:

interface Flyable {
    fly(): void;
}

interface Swimmable {
    swim(): void;
}

class Duck implements Flyable, Swimmable {
    fly(): void {
        console.log("Duck is flying");
    }

    swim(): void {
        console.log("Duck is swimming");
    }
}