给个网站谢谢各位了,农夫山泉软文300字,深圳建网站需要多少钱,邯郸房产信息网查询系统一、装饰器核心作用与启用
1. 本质与定位
元编程工具#xff1a;在编译阶段动态修改类/方法/属性的行为#xff08;不改变源码#xff09;启用配置#xff1a;需在 tsconfig.json 中开启#xff1a; {compilerOptions: {expe…
一、装饰器核心作用与启用
1. 本质与定位
元编程工具在编译阶段动态修改类/方法/属性的行为不改变源码启用配置需在 tsconfig.json 中开启 {compilerOptions: {experimentalDecorators: true,emitDecoratorMetadata: true // 支持反射元数据}
}
2. 五大类型与参数
类型作用目标接收参数类装饰器类构造函数target: Function构造函数方法装饰器类方法target: any, propertyKey: string, descriptor: PropertyDescriptor属性装饰器类属性target: any, propertyKey: string参数装饰器方法参数target: any, propertyKey: string, parameterIndex: number访问器装饰器getter/setter同方法装饰器 二、工程化应用场景详解
1. 增强代码可维护性 日志跟踪自动记录方法调用参数与耗时 function LogMethod(target: any, key: string, descriptor: PropertyDescriptor) {const original descriptor.value;descriptor.value function (...args: any[]) {console.log([${new Date()}] 调用方法 ${key}参数:, args);return original.apply(this, args);};
}class UserService {LogMethodgetUser(id: number) { /* 业务逻辑 */ }
} 性能监控统计关键方法执行时间 function MeasureTime(target: any, key: string, descriptor: PropertyDescriptor) {const original descriptor.value;descriptor.value function (...args: any[]) {const start performance.now();const result original.apply(this, args);console.log(方法 ${key} 耗时: ${performance.now() - start}ms);return result;};
}
2. 提升系统健壮性 数据验证自动校验参数或属性合法性 function ValidateEmail(target: any, key: string) {let value target[key];Object.defineProperty(target, key, {set: (newVal) {if (!/^\S\S\.\S$/.test(newVal)) throw new Error(邮箱格式错误);value newVal;}});
}class User {ValidateEmailemail!: string;
} 权限控制拦截未授权操作 function Permission(role: string) {return (target: any, key: string, descriptor: PropertyDescriptor) {const original descriptor.value;descriptor.value function (...args: any[]) {if (!currentUser.roles.includes(role)) throw new Error(权限不足);return original.apply(this, args);};};
}class AdminService {Permission(ADMIN)deleteUser() { /* 敏感操作 */ }
}
3. 框架级应用 依赖注入 (DI)自动实例化依赖对象如 Angular/NestJS // 模拟 Angular 的 Injectable
function Injectable() {return (target: Function) {// 注册到 DI 容器Container.register(target.name, new target());};
}Injectable()
class LoggerService {log(message: string) { console.log(message); }
} 路由绑定声明式 API 路由配置如 Express 框架 function Get(path: string) {return (target: any, key: string) {Router.register(GET, path, target[key]);};
}class UserController {Get(/users)getUsers() { /* 返回用户列表 */ }
}
4. 设计模式实现 AOP面向切面分离业务逻辑与横切关注点 function Transactional(target: any, key: string, descriptor: PropertyDescriptor) {const original descriptor.value;descriptor.value async function (...args: any[]) {const tx startTransaction(); // 开启事务try {const result await original.apply(this, args);tx.commit(); // 提交事务return result;} catch (error) {tx.rollback(); // 回滚事务throw error;}};
} 装饰器工厂动态生成定制化装饰器 function Cache(duration: number) {return (target: any, key: string, descriptor: PropertyDescriptor) {const cache new Map();const original descriptor.value;descriptor.value function (...args: any[]) {const cacheKey JSON.stringify(args);if (cache.has(cacheKey)) return cache.get(cacheKey);const result original.apply(this, args);cache.set(cacheKey, result);setTimeout(() cache.delete(cacheKey), duration);return result;};};
}class WeatherService {Cache(60000) // 缓存1分钟getForecast(city: string) { /* 调用API */ }
} 三、开发实践建议 组合优于继承 通过装饰器叠加功能如日志权限缓存避免深度继承链。 元数据反射 结合 reflect-metadata 库实现高级场景如类型序列化。 调试技巧 使用 descriptor.value 保留原始方法引用避免在装饰器内直接修改 target 原型破坏封装性 框架选择 框架装饰器应用重点Angular依赖注入、组件生命周期挂钩NestJS控制器路由、中间件拦截器TypeORM实体字段映射、数据库关系定义 总结 装饰器通过 非侵入式增强 解决了代码重复问题如日志/验证在框架开发、AOP 编程、元数据管理等场景优势显著。需注意其仍为实验性特性建议在严格类型约束下使用避免过度抽象。