J*aScript装饰器与元数据编程


装饰器是J*aScript/TypeScript中用于扩展类、方法等行为的高阶函数,通过@expression语法在运行时修改目标结构。支持类、方法、属性、访问器和参数五种类型,常用于日志、权限、依赖注入等场景。结合reflect-metadata库可实现元数据编程,使用Reflect.metadata定义和读取键值对信息,TypeScript还支持design:type等设计时类型元数据。典型应用如依赖注入:通过@Inject装饰参数并利用emitDecoratorMetadata生成类型信息,容器按需实例化并注入依赖。需启用experimentalDecorators和emitDecoratorMetadata编译选项。该技术广泛用于Angular、NestJS等框架,提升代码可维护性与扩展性。

javascript装饰器与元数据编程

J*aScript 装饰器和元数据编程是现代前端开发中越来越重要的技术,尤其在使用 TypeScript 和框架如 Angular、NestJS 时广泛存在。它们让开发者可以在类、方法、属性等代码结构上附加额外行为或信息,实现更灵活的元编程能力。

装饰器是什么?

装饰器是一种特殊类型的声明,可以被附加到类声明、方法、访问器、属性或参数上。它使用 @expression 的形式,其中 expression 必须是一个函数,该函数会在运行时被调用,传入被装饰的 target、key 和 property descriptor 等信息。

装饰器本质是一个高阶函数,通过闭包捕获配置,并返回一个处理目标的函数。例如:

function Log(target: any, propertyName: string) {
  console.log(`Property ${propertyName} of`, target);
}
<p>class User {
@Log
name = 'Alice';
}</p>

上面的例子中,@Log 将在类定义时执行,打印出被修饰的属性名。

装饰器的类型与使用场景

J*aScript/TypeScript 支持多种装饰器,每种用于不同的语法结构:

  • 类装饰器:作用于类构造函数,可用于修改类行为或替换类定义。常用于依赖注入或路由注册。
  • 方法装饰器:接收目标原型、方法名和描述符,适合做日志、权限控制、缓存等切面操作。
  • 访问器装饰器:应用于 getter/setter,可监控或拦截访问逻辑。
  • 属性装饰器:用于标记字段,通常不直接改变行为,而是记录元数据。
  • 参数装饰器:标注构造函数或方法中的某个参数,常用于依赖注入容器识别类型。

比如一个简单的性能监控方法装饰器:

function Measure(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;
<p>descriptor.value = function (...args: any[]) {
console.time(propertyKey);
const result = originalMethod.apply(this, args);
console.timeEnd(propertyKey);
return result;
};</p><p>return descriptor;
}</p><p>class Calculator {
@Measure
fib(n: number): number {
if (n < 2) return n;
return this.fib(n - 1) + this.fib(n - 2);
}
}</p>

元数据反射(Metadata Reflection)

装饰器本身不能直接存储任意数据,但结合 reflect-metadata 库,可以实现真正的元数据编程。这个库允许你在类或方法上读写键值对形式的元数据。

启用元数据需要安装 reflect-metadata 并引入:

php中级教程之ajax技术 php中级教程之ajax技术

AJAX即“Asynchronous J*ascript And XML”(异步J*aScript和XML),是指一种创建交互式网页应用的网页开发技术。它不是新的编程语言,而是一种使用现有标准的新方法,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,不需要任何浏览器插件,但需要用户允许J*aScript在浏览器上执行。《php中级教程之ajax技术》带你快速

php中级教程之ajax技术 2114 查看详情 php中级教程之ajax技术
import 'reflect-metadata';
<p>const TYPE_KEY = 'design:type';
const ROLE_KEY = 'custom:role';</p><p>function Role(role: string) {
return Reflect.metadata(ROLE_KEY, role);
}</p><p>@Role('admin')
class DashboardController {
@Role('guest')
getData() {}
}</p><p>// 读取元数据
const role = Reflect.getMetadata(ROLE_KEY, DashboardController.prototype, 'getData');
console.log(role); // 'guest'
</font>

这里用到了两个层级的元数据:类上的角色和方法上的角色。Reflect 提供了 getMetadata、defineMetadata、hasMetadata 等 API,便于构建依赖注入、序列化、验证系统。

TypeScript 还内置支持一些设计时元数据,如 design:typedesign:paramtypesdesign:returntype,开启 emitDecoratorMetadata 后会自动注入类型信息。

实际应用:依赖注入示例

利用装饰器和元数据,可以实现轻量级依赖注入容器:

import 'reflect-metadata';
<p>const INJECT_KEY = 'di:inject';</p><p>function Inject(token: any) {
return (target: any, propertyKey: string | undefined, parameterIndex: number) => {
const existingTokens = Reflect.getMetadata(INJECT_KEY, target, 'constructor') || [];
existingTokens[parameterIndex] = token;
Reflect.defineMetadata(INJECT_KEY, existingTokens, target, 'constructor');
};
}</p><p>class DatabaseService {}
class LoggerService {}</p><p>class UserService {
constructor(
@Inject(DatabaseService) private db: DatabaseService,
@Inject(LoggerService) private logger: LoggerService
) {}
}</p><p>// 容器解析依赖
function createInstance<T>(target: any): T {
const tokens = Reflect.getMetadata(INJECT_KEY, target, 'constructor') || [];
const dependencies = tokens.map((token: any) => new token());
return new target(...dependencies);
}</p><p>const userSvc = createInstance<UserService>(UserService);</p>

这个例子展示了如何通过参数装饰器标记依赖,并在运行时由容器自动解析并实例化。

基本上就这些。装饰器结合元数据提供了强大的抽象能力,虽然原生 J*aScript 还未正式支持(目前处于 Stage 3),但在 TypeScript 中已非常成熟,是构建可维护、可扩展框架的核心工具之一。注意合理使用,避免过度元编程导致调试困难。不复杂但容易忽略的是:确保正确配置 tsconfig.json 中的 experimentalDecorators 和 emitDecoratorMetadata 选项。基本上就这些。

以上就是J*aScript装饰器与元数据编程的详细内容,更多请关注其它相关文章!


# javascript  # 装饰器  # 是一个  # 如何实现  # 键值  # 键值对  # 路由  # 前端开发  # 工具  # app  # typescript  # json  # 前端  # js  # java  # 卤菜如何营销广告推广  # 如何做物流信息网站推广  # 武汉网站优化地址  # 咸宁网站建设作用  # 淘宝新店营销推广  # 绵阳网站的推广工作  # 建瓯优化seo  # 苏州网站推广工作内容  # 新沂推广网站建设  # 抚顺关键词排名优化案例  # 路由功能  # 是一种  # 是在  # 的是  # 高阶  # 可以实现  # 加载 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 店铺如何关联视频号推广?视频号推广有什么用?  123平台官方登录入口 123邮箱网页端在线沟通工具  《原神》月之一版本新增书籍一览  抖音如何进行蓝V认证 抖音企业号申请所需资料与流程  Microsoft Edge网页字体太淡看不清怎么办_Microsoft Edge字体渲染优化技巧  处理含命名空间的XML文件 Power Query中的高级技巧  PPT页面尺寸怎么修改 PPT自定义幻灯片大小与方向设置【教程】  酷狗音乐多音轨设置教程  PHP中实现JSON数据数组分页的教程  附近酒吧怎么找?  React应用中Commerce.js数据加载与状态管理最佳实践  Python测试中模块导入路径解析的最佳实践  包子漫画官网链接官方地址 包子漫画在线观看官网首页入口  虫虫助手如何更新游戏  mysql导入sql文件能分批导入吗_mysql分批次导入大sql文件的实用技巧  韩小圈网页版PC端入口 韩小圈网页版官方网站入口  Windows Audio服务启动失败怎么办_电脑没声音的终极服务修复法【修复】  C++ static关键字作用_C++静态成员变量与静态函数  Word 2003字体大小设置方法  快手缓存清理方法  如何用mysql实现客户反馈管理_mysql客户反馈数据库方法  电脑开不了机怎么办 电脑无法开机的解决方法  照片整理的黄金法则是怎样的? 理解“收集-筛选-归档-备份”四步流程  PDF文件去水印平台入口 PDF水印删除网址  Linux如何优化系统启动流程_Linux启动项优化方案  电脑双系统如何安装和卸载 Windows和Linux双系统安装教程【详解】  抖音小程序怎么开通?小程序开通条件是什么?  rabbitmq 持久化有什么缺点?  使用 J*aScript 随机化 CSS Grid 布局中的元素顺序  优化Google Charts Gauge:在数据库无数据时显示默认值  AO3中文入口稳定分享_AO3官网HTTPS看文详解  抖音网页版地址直接进入_抖音网页版在线观看入口  Python模块化编程:避免循环导入与共享函数的最佳实践  实时数据流中高效查找最小值与最大值  在Dash应用中自定义HTML标题和网站图标  TikTok笔记文字无法编辑如何解决 TikTok笔记文字编辑优化方法  《KARDS》冬季扩展包“国土阵线”上线!全新“协力”机制改变战场格局  抖音手机分身两个账号怎么切换?分身两个系统是一样的吗?  J*aScript与CSS动画:实现平滑顺序淡入淡出效果并解决显示冲突  composer licenses 命令:如何检查项目依赖的许可证?  火狐浏览器如何刷新修复浏览器 火狐浏览器“重置Firefox”功能详解  路由器DNS怎么设置最快 优化DNS提升上网速度教程  《盗墓笔记手游》技能介绍  163邮箱网页版入口 163邮箱在线使用  139邮箱登录入口官网 139邮箱登录入口官网网址  吃完饭就犯困是什么原因 餐后嗜睡如何缓解  iPhone 13 mini如何清理Safari缓存_iPhone 13 mini浏览器缓存清理方法  mysql通配符能用于日志查询吗_mysql通配符在系统日志查询中的实际使用方法  《飞猪旅行》购买汽车票方法  Go反射进阶:访问内嵌结构体中的被遮蔽方法 

 2025-10-21

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.