元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
TypeScript环境准备
安装与配置
第一个TS程序
编译流程解析
▶
基础类型系统
类型注解语法
原始类型定义
数组与元组
接口与对象
▶
高级类型系统
泛型编程
条件类型
映射类型
类型推断
类型保护
高级类型工具
▶
函数开发
函数类型声明
可选参数与默认值
箭头函数应用
函数重载
泛型函数
▶
类与面向对象
类的定义
继承与修饰符
存取器使用
抽象类与接口
泛型类与抽象类
访问修饰符与属性
▶
模块化开发
模块导入导出
类型声明文件
命名空间
模块解析策略
▶
工程实践
tsconfig详解
常见编译选项
项目构建配置
代码组织最佳实践
单元测试
调试技巧
▶
常见问题
类型错误处理
类型断言技巧
类型兼容性
版本迁移指南
发布时间:
2025-03-31 09:26
↑
☰
# 访问修饰符与属性 TypeScript提供了多种访问修饰符来控制类成员的可访问性,以及不同类型的属性来满足各种编程需求。本文将详细介绍这些特性的使用方法。 ## 访问修饰符 ### public修饰符 ```typescript class Employee { // 默认为public name: string; // 显式声明public public department: string; constructor(name: string, department: string) { this.name = name; this.department = department; } // public方法 public getInfo(): string { return `${this.name} works in ${this.department}`; } } const employee = new Employee("John", "IT"); console.log(employee.name); // 可以访问 console.log(employee.department); // 可以访问 console.log(employee.getInfo()); // 可以访问 ``` ### private修饰符 ```typescript class BankAccount { private balance: number; private readonly accountNumber: string; constructor(initialBalance: number) { this.balance = initialBalance; this.accountNumber = Math.random().toString(36).substr(2, 9); } public deposit(amount: number): void { if (amount > 0) { this.balance += amount; } } public getBalance(): number { return this.balance; } private validateAmount(amount: number): boolean { return amount > 0 && amount <= this.balance; } } const account = new BankAccount(1000); // account.balance = 2000; // 错误:'balance'为私有属性 // account.validateAmount(500); // 错误:'validateAmount'为私有方法 ``` ### protected修饰符 ```typescript class Person { protected id: string; protected age: number; constructor(id: string, age: number) { this.id = id; this.age = age; } protected getDetails(): string { return `ID: ${this.id}, Age: ${this.age}`; } } class Student extends Person { private grade: number; constructor(id: string, age: number, grade: number) { super(id, age); this.grade = grade; } public getStudentInfo(): string { // 可以访问protected成员 return `${this.getDetails()}, Grade: ${this.grade}`; } } ``` ## 属性特性 ### 只读属性 ```typescript class Configuration { readonly apiKey: string; readonly maxRetries: number = 3; constructor(apiKey: string) { this.apiKey = apiKey; } } const config = new Configuration("abc123"); // config.apiKey = "xyz789"; // 错误:无法分配到'apiKey',因为它是只读属性 ``` ### 参数属性 ```typescript class Product { constructor( public name: string, private price: number, protected category: string, readonly id: string ) {} public getPrice(): number { return this.price; } } // 等同于 class ProductVerbose { public name: string; private price: number; protected category: string; readonly id: string; constructor(name: string, price: number, category: string, id: string) { this.name = name; this.price = price; this.category = category; this.id = id; } } ``` ### 静态属性 ```typescript class MathUtils { static readonly PI: number = 3.14159; private static counter: number = 0; static increment(): void { MathUtils.counter++; } static getCount(): number { return MathUtils.counter; } } console.log(MathUtils.PI); // 3.14159 MathUtils.increment(); console.log(MathUtils.getCount()); // 1 ``` ## 存取器 ```typescript class Employee { private _salary: number; constructor(private name: string, salary: number) { this._salary = salary; } // 获取器 get salary(): number { return this._salary; } // 设置器 set salary(value: number) { if (value >= 0) { this._salary = value; } else { throw new Error("Salary cannot be negative"); } } } const emp = new Employee("John", 50000); console.log(emp.salary); // 使用获取器 emp.salary = 60000; // 使用设置器 ``` ## 最佳实践 1. **合理使用访问修饰符**: ```typescript class User { private password: string; // 敏感数据使用private protected id: string; // 继承相关使用protected public name: string; // 公共接口使用public constructor(name: string, password: string) { this.name = name; this.password = password; this.id = Math.random().toString(36).substr(2, 9); } } ``` 2. **使用存取器控制属性访问**: ```typescript class Temperature { private _celsius: number = 0; get celsius(): number { return this._celsius; } set celsius(value: number) { this._celsius = value; } get fahrenheit(): number { return (this._celsius * 9/5) + 32; } set fahrenheit(value: number) { this._celsius = (value - 32) * 5/9; } } ``` 3. **使用readonly防止修改**: ```typescript class ApiClient { constructor( readonly baseUrl: string, readonly timeout: number = 5000 ) {} makeRequest(): void { // 使用但不能修改readonly属性 console.log(`Making request to ${this.baseUrl}`); } } ``` ## 常见问题 1. **私有字段vs私有属性**: ```typescript class Example { #realPrivate: string; // ECMAScript私有字段 private typeScriptPrivate: string; // TypeScript私有属性 constructor() { this.#realPrivate = "truly private"; this.typeScriptPrivate = "compile-time private"; } } ``` 2. **protected vs private**: ```typescript class Base { private privateVar = "private"; protected protectedVar = "protected"; } class Derived extends Base { method() { // console.log(this.privateVar); // 错误:无法访问私有属性 console.log(this.protectedVar); // 正确:可以访问protected属性 } } ``` ## 下一步 掌握了访问修饰符和属性后,你可以: 1. 学习更多面向对象设计模式 2. 探索装饰器的使用 3. 实践依赖注入 4. 了解更多TypeScript高级特性 通过合理使用访问修饰符和属性,你可以创建更加安全和可维护的面向对象代码。