第5章:类与面向对象编程
访问修饰符(public, private, protected)
在 TypeScript 中,访问修饰符用于控制类成员(属性和方法)的可访问性。它们帮助开发者实现封装原则,明确哪些成员可以被外部访问,哪些仅限内部使用。TypeScript 提供了三种主要的访问修饰符:public、private 和 protected。
1. public(默认修饰符)
- 作用:成员可以在任何地方被访问,包括类内部、子类以及类实例。
- 特点:
- 如果未显式指定修饰符,默认为
public。 - 通常用于公开的 API 或需要外部直接访问的成员。
- 如果未显式指定修饰符,默认为
- 示例:
class Person { public name: string; // 显式声明为 public(可省略) constructor(name: string) { this.name = name; } } const person = new Person("Alice"); console.log(person.name); // 允许访问
2. private
- 作用:成员仅能在定义它的类内部访问,子类和实例均无法访问。
- 特点:
- 强制封装,避免外部直接修改敏感数据。
- 编译后会通过
WeakMap实现(ES5 及以上目标)。
- 示例:
class BankAccount { private balance: number; constructor(initialBalance: number) { this.balance = initialBalance; } public deposit(amount: number) { this.balance += amount; // 类内部可访问 } } const account = new BankAccount(1000); console.log(account.balance); // 编译错误:Property 'balance' is private
3. protected
- 作用:成员可在类内部和子类中访问,但实例无法直接访问。
- 特点:
- 适用于需要被子类继承但对外隐藏的成员。
- 常用于基类的工具方法或受保护的状态。
- 示例:
class Animal { protected age: number; constructor(age: number) { this.age = age; } } class Dog extends Animal { public getAge() { return this.age; // 子类可访问 } } const dog = new Dog(3); console.log(dog.age); // 编译错误:Property 'age' is protected console.log(dog.getAge()); // 允许通过公开方法访问
对比总结
| 修饰符 | 类内部 | 子类 | 实例 |
|---|---|---|---|
public | ✔ | ✔ | ✔ |
protected | ✔ | ✔ | ✖ |
private | ✔ | ✖ | ✖ |
注意事项
- 编译时的限制:访问修饰符仅在 TypeScript 编译阶段生效,编译后的 JavaScript 代码中不会保留这些限制。
- 兼容性:若目标为 ES3 或 ES5,
private和protected会降级为普通属性,但编译器仍会检查访问权限。 - 替代方案:ECMAScript 的私有字段语法(
#field)是 JavaScript 原生私有成员方案,与 TypeScript 的private修饰符共存但互不冲突。
最佳实践
- 优先使用
private或protected保护内部状态,避免直接暴露属性。 - 通过公开方法(如
getter/setter)控制对私有成员的访问,便于后续扩展验证逻辑。
