在TypeScript中的getter/setter是什么?有什么作用?

288 阅读4分钟

"### 在TypeScript中的getter/setter是什么?有什么作用?

TypeScript中的getter和setter是对象属性的访问器方法,用于控制对象属性的获取和赋值操作。它们允许你对类中的属性进行更精细的控制,常用于数据验证、懒加载、计算属性等场景。

1. getter与setter的定义

在TypeScript中,getter和setter分别通过getset关键字来定义。它们是对象属性的特殊方法,分别在访问对象的属性时自动触发。

Getter:用于获取对象属性的值。它没有参数,只能用于返回一个计算值。

class Person {
  private _name: string;

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

  // Getter方法
  get name(): string {
    return this._name;
  }
}

const person = new Person(\"John\");
console.log(person.name); // 通过getter获取属性值,输出\"John\"

Setter:用于设置对象属性的值。它接受一个参数,在赋值时执行一些额外的操作。

class Person {
  private _name: string;

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

  // Setter方法
  set name(value: string) {
    if (value.trim() === \"\") {
      throw new Error(\"Name cannot be empty\");
    }
    this._name = value;
  }
}

const person = new Person(\"John\");
person.name = \"Jane\"; // 通过setter修改属性值
console.log(person.name); // 输出\"Jane\"

2. getter/setter的作用

getter和setter在TypeScript中有多个重要的作用和用途,主要包括以下几点:

2.1 数据验证

通过使用setter方法,可以对属性赋值进行验证,确保对象的状态始终有效。例如,在设置用户年龄时,我们可以确保年龄不能为负数。

class User {
  private _age: number;

  constructor(age: number) {
    this._age = age;
  }

  set age(value: number) {
    if (value < 0) {
      throw new Error(\"Age cannot be negative\");
    }
    this._age = value;
  }

  get age(): number {
    return this._age;
  }
}

const user = new User(30);
user.age = -5; // 会抛出错误:Age cannot be negative
2.2 计算属性

getter方法常用于计算属性值。当属性值依赖于其他属性时,可以通过getter实现动态计算,而不需要显式地进行计算。例如:

class Rectangle {
  constructor(private _width: number, private _height: number) {}

  // 计算属性
  get area(): number {
    return this._width * this._height;
  }
}

const rect = new Rectangle(10, 5);
console.log(rect.area); // 计算矩形的面积,输出50
2.3 懒加载(Lazy Loading)

getter方法也可以用于懒加载。当属性的计算或获取代价很高时,可以在第一次访问时计算并缓存结果,之后的访问将直接返回缓存值,从而提高性能。

class ExpensiveCalculation {
  private _result: number | null = null;

  // 懒加载计算结果
  get result(): number {
    if (this._result === null) {
      console.log(\"Performing expensive calculation...\");
      this._result = Math.random() * 100;
    }
    return this._result;
  }
}

const calc = new ExpensiveCalculation();
console.log(calc.result); // 第一次计算并返回结果
console.log(calc.result); // 后续访问直接返回缓存的结果
2.4 数据封装和抽象

getter和setter提供了一种封装的方式,允许你在不暴露实现细节的情况下对属性进行操作。通过getter和setter,可以隐藏内部属性的具体实现,让外部代码只关注接口。

class BankAccount {
  private _balance: number;

  constructor(initialBalance: number) {
    this._balance = initialBalance;
  }

  // Getter用于访问余额
  get balance(): number {
    return this._balance;
  }

  // Setter用于修改余额
  set balance(amount: number) {
    if (amount < 0) {
      throw new Error(\"Balance cannot be negative\");
    }
    this._balance = amount;
  }
}

const account = new BankAccount(1000);
console.log(account.balance); // 获取余额,输出1000
account.balance = 1200; // 设置新余额
console.log(account.balance); // 输出1200

3. getter与setter的使用注意事项

3.1 不能同时定义getter和setter

一个属性不能同时定义getter和setter。如果你定义了getter方法,那么可以选择性地定义setter方法;如果你没有定义setter方法,属性就变成了只读属性。反之亦然。

class Person {
  private _age: number;

  constructor(age: number) {
    this._age = age;
  }

  // 只读属性
  get age(): number {
    return this._age;
  }

  // 只写属性
  set age(value: number) {
    if (value < 0) {
      throw new Error(\"Age cannot be negative\");
    }
    this._age = value;
  }
}
3.2 setter可以有副作用

setter方法中可以包含副作用,比如验证、格式化数据或者触发其他操作。但要注意,setter方法应该尽量保持简洁明了,避免过多的逻辑影响代码的可维护性。

3.3 getter不能有副作用

getter方法应该避免有副作用。getter的设计目标是简单、快速地返回一个值。如果在getter中执行复杂的操作或修改状态,可能会导致代码难以理解和维护。

4. 总结

在TypeScript中,getter和setter是访问对象属性的强大工具,它们允许你:

  • 控制属性的读取和修改;
  • 验证和转换数据;
  • 实现懒加载和计算属性;
  • 隐藏实现细节,提供更好的数据封装。

通过合理使用getter和setter,你可以使代码更加灵活、可维护,并能有效地管理对象的状态。"