两种常见的导出方式
1. 类导出
// 传统类导出
export class MyService {
constructor() {}
doSomething() {}
}
// 使用时需要实例化
import { MyService } from './my-service';
const service = new MyService();
2. 实例导出
// 直接导出实例
class MyService {
constructor() {}
doSomething() {}
}
export default new MyService();
// 使用时直接使用实例
import myService from './my-service';
myService.doSomething();
各自的应用场景
类导出适用于:
- 需要多个实例的场景
- 需要通过构造函数传参的场景
- 实例需要独立的状态管理
- 测试时需要 mock 不同实例
实例导出适用于:
- 全局共享状态的场景
- 工具类服务
- 配置管理服务
- 需要确保单例的场景
实现原理
类导出的实现:
// service.ts
export class Service {
private state = {};
constructor(config) {
this.init(config);
}
}
// usage.ts
import { Service } from './service';
const serviceA = new Service(configA);
const serviceB = new Service(configB);
实例导出的实现:
// service.ts
class Service {
private static instance: Service;
private constructor() {}
public static getInstance() {
if (!Service.instance) {
Service.instance = new Service();
}
return Service.instance;
}
}
export default Service.getInstance();
// 或者更简单的方式
class Service {}
export default new Service();
性能考虑
- 内存占用:
- 类导出:每个实例都占用独立内存
- 实例导出:全局共享一份内存
- 初始化时机:
- 类导出:使用时才初始化
- 实例导出:模块加载时就初始化
最佳实践
- 工具类服务:使用实例导出
// date-formatter.ts
class DateFormatter {
format() {}
}
export default new DateFormatter();
- 业务服务:使用类导出
// user-service.ts
export class UserService {
constructor(userId: string) {}
getProfile() {}
}
总结
选择哪种导出方式应该基于:
- 是否需要多实例
- 是否需要共享状态
- 初始化时机的要求
- 测试的便利性
- 内存使用的考虑
合理选择导出方式可以让代码更加清晰、易维护,同时避免不必要的性能开销。