TS中的装饰器及执行顺序

装饰器是一种元编程机制,用于在运行时修改或增强类、方法、属性和参数的行为。本文详细介绍了如何定义和使用类装饰器、方法装饰器、参数装饰器和属性装饰器,以及它们的执行顺序和应用场景。示例代码展示了如何实现类和方法的装饰,以及参数和属性的装饰。装饰器在 TypeScript 中需要开启 `experimentalDecorators` 编译选项才能使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念

装饰器是一种特殊类型的声明,它能够被附加到类声明方法, 访问符属性参数上。 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。

必须在命令行或tsconfig.json里启用experimentalDecorators编译器选项

tsc --target ES5 --experimentalDecorators
{
    "compilerOptions": {
        "target": "ES5",   //"target": "es6",
        "experimentalDecorators": true
    }
}

如何定义装饰器

function helloWord(target: any) {
    console.log('hello Word!');
}

@helloWord
class HelloWordClass {

}

console.log(HelloWordClass)  //hello Word!

类型

类装饰器

应用于类构造函数,其参数是类的构造函数。

function GET(url: string) {
    return function (target, methodName: string, descriptor: PropertyDescriptor) {
        !target.$Meta && (target.$Meta = {});
        target.$Meta[methodName] = url;
    }
}

class HelloService {
    constructor() { }
    @GET("xx")
    getUser() { }
}

console.log((<any>HelloService).$Meta);

方法参数装饰器

参数装饰器表达式会在运行时当作函数被调用,传入下列3个参数:

  • 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  • 2、参数的名字。
  • 3、参数在函数参数列表中的索引。
function PathParam(paramName: string) {
    return function (target, methodName: string, paramIndex: number) {
        !target.$Meta && (target.$Meta = {});
        target.$Meta[paramIndex] = paramName;
    }
}

class HelloService {
    constructor() { }
    getUser( @PathParam("userId") userId: string) { }
}

console.log((<any>HelloService).prototype.$Meta); // {'0':'userId'}

方法装饰器

它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰会在运行时传入下列3个参数:

  • 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  • 2、成员的名字。
  • 3、成员的属性描述符。
function GET(url: string) {
    return function (target, methodName: string, descriptor: PropertyDescriptor) {
        !target.$Meta && (target.$Meta = {});
        target.$Meta[methodName] = url;
    }
}

class HelloService {
    constructor() { }
    @GET("xx")
    getUser() { }
}

console.log((<any>HelloService).$Meta);

属性装饰器

属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:

  • 1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
  • 2、成员的名字。
function cls(value: string) {
    return function (target: any, propertyName: string) {
        target[propertyName] = value;
    }
}

class Hello {
    @cls("lc") greeting: string;
}

console.log(new Hello().greeting);// 输出: lc

执行顺序

属性>方法>方法参数>类        注:如果有多个同样的装饰器,它会先执行后面的装饰器。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温柔于心动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值