类的基本语法

类是面向对象编程的核心概念,它提供了一种组织代码的方式,将数据和操作数据的方法封装在一起。TypeScript 在 JavaScript 类的基础上增加了类型注解,让代码更加安全可靠。

定义类

使用 class 关键字定义类,类名通常使用大驼峰命名法。

class Person {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  introduce(): string {
    return `我是 ${this.name},今年 ${this.age} 岁`
  }
}

这个 Person 类有三个组成部分:属性声明、构造函数和方法。属性声明定义了实例的数据类型,构造函数用于初始化实例,方法定义了实例的行为。

构造函数

constructor 是类的构造函数,在使用 new 创建实例时自动调用。构造函数用于初始化实例的属性。

class Book {
  title: string
  author: string
  price: number

  constructor(title: string, author: string, price: number) {
    this.title = title
    this.author = author
    this.price = price
  }
}

const book = new Book("TypeScript 入门", "张三", 59.9)
console.log(book.title)
console.log(book.author)

每个类只能有一个构造函数。如果不需要初始化逻辑,可以省略构造函数,TypeScript 会提供默认的空构造函数。

创建实例

使用 new 关键字创建类的实例,实例是类的具体对象。

class Counter {
  count: number = 0

  increment(): void {
    this.count++
  }

  decrement(): void {
    this.count--
  }
}

const counter1 = new Counter()
const counter2 = new Counter()

counter1.increment()
counter1.increment()
counter2.increment()

console.log(counter1.count)
console.log(counter2.count)

每个实例都有独立的属性,修改一个实例不会影响其他实例。

属性声明

在类体中声明属性,必须指定类型。属性可以在声明时初始化,也可以在构造函数中赋值。

class User {
  id: number
  name: string = "匿名用户"
  email: string
  age: number = 0

  constructor(id: number, email: string) {
    this.id = id
    this.email = email
  }
}

const user = new User(1, "test@example.com")
console.log(user.name)
console.log(user.age)

nameage 在声明时就有默认值,idemail 在构造函数中赋值。

方法定义

类的方法定义了实例的行为,方法内部可以通过 this 访问实例的属性和其他方法。

class Calculator {
  value: number = 0

  add(n: number): void {
    this.value += n
  }

  subtract(n: number): void {
    this.value -= n
  }

  multiply(n: number): void {
    this.value *= n
  }

  divide(n: number): void {
    if (n !== 0) {
      this.value /= n
    }
  }

  getValue(): number {
    return this.value
  }
}

const calc = new Calculator()
calc.add(10)
calc.multiply(2)
calc.subtract(5)
console.log(calc.getValue())

方法可以有参数和返回值,语法与普通函数相同。

this 的使用

在类的方法中,this 指向当前实例。但需要注意 this 的绑定问题。

class Logger {
  prefix: string

  constructor(prefix: string) {
    this.prefix = prefix
  }

  log(message: string): void {
    console.log(`[${this.prefix}] ${message}`)
  }
}

const logger = new Logger("APP")
logger.log("启动成功")

const logFn = logger.log
logFn("测试")

当方法被单独调用时,this 可能丢失。可以使用箭头函数或 bind 来解决这个问题。

class Logger {
  prefix: string

  constructor(prefix: string) {
    this.prefix = prefix
    this.log = this.log.bind(this)
  }

  log = (message: string): void => {
    console.log(`[${this.prefix}] ${message}`)
  }
}

const logger = new Logger("APP")
const logFn = logger.log
logFn("测试成功")

使用箭头函数定义方法可以自动绑定 this,避免绑定问题。

类的继承

使用 extends 关键字实现继承,子类可以继承父类的属性和方法。

class Animal {
  name: string

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

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

class Dog extends Animal {
  breed: string

  constructor(name: string, breed: string) {
    super(name)
    this.breed = breed
  }

  speak(): void {
    console.log(`${this.name} 汪汪叫`)
  }
}

const dog = new Dog("小黑", "拉布拉多")
dog.speak()

子类在构造函数中必须调用 super(),这会执行父类的构造函数。子类可以重写父类的方法。

实例属性与原型方法

实例属性是每个实例独有的数据,原型方法是所有实例共享的函数。

class Student {
  name: string
  score: number

  constructor(name: string, score: number) {
    this.name = name
    this.score = score
  }

  isPassed(): boolean {
    return this.score >= 60
  }
}

const s1 = new Student("张三", 85)
const s2 = new Student("李四", 55)

console.log(s1.isPassed())
console.log(s2.isPassed())

namescore 是实例属性,每个学生有自己的名字和分数。isPassed 是原型方法,所有学生实例共享同一个函数。

类表达式

除了类声明,还可以使用类表达式来定义类。

const Animal = class {
  name: string

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

const Cat = class CatImpl {
  name: string

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

  meow(): void {
    console.log(`${this.name} 喵喵叫`)
  }
}

const cat = new Cat("小白")
cat.meow()

类表达式可以匿名也可以命名,命名后的类名只在类内部可见。

小结

类的基本语法包括属性声明、构造函数、方法定义和实例创建。通过类,我们可以将相关的数据和行为组织在一起,构建清晰的代码结构。掌握类的基本语法是学习 TypeScript 面向对象编程的第一步。