TS中的装饰器及执行顺序

Posted 青袂婉梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TS中的装饰器及执行顺序相关的知识,希望对你有一定的参考价值。

概念

装饰器是一种特殊类型的声明,它能够被附加到类声明方法, 访问符属性参数上。 装饰器使用 @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

执行顺序

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

以上是关于TS中的装饰器及执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码

代码缺乏装饰?使用ts装饰器来装饰你的代码

Python @函数装饰器及用法

装饰器及模块

Python3——装饰器及应用(这个属于详细的)