Skip to content

装饰器函数

TypeScript中装饰器还属于实验性语法,所以要想使用必须在配置文件中tsconfig.json编译选项中开启:

json
{
    "compilerOptions": {
        "experimentalDecorators": true
    }
}

假设class中有一个方法,我们调试的时候会添加一些log进去,装饰器可以让这些过程变得简单,第一个参数是待修饰的函数,第二个参数是上下文

ts
function loggedMethod(originalMethod: any, _context: ClassMethodDecoratorContext) {
    const methodName = String(_context.name);

    function replacementMethod(this: any, ...args: any[]) {
        console.log(`LOG: Entering method '${methodName}'.`)
        const result = originalMethod.call(this, ...args);
        console.log(`LOG: Exiting method '${methodName}'.`)
        return result;
    }
    return replacementMethod;
}

class Person {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    @loggedMethod
    greet() {
        console.log(`Hello, my name is ${this.name}.`);
    }
}

const p = new Person("Ray");
p.greet();

装饰器的种类

类装饰器(无法传参)

ts
function logClass(params:any) {
    // 这里的 parmas 默认表示被监视的类
    params.prototype.name = 'xxl' // 给类 添加属性

    // 给类 添加方法
    params.prototype.getUrl = function() {
        return this.name + '123'
    }
}

// 装饰饰后面不能加 分号 ;
@logClass
class Animal{
    
    constructor() {
    }
}

// 这里要加个:any,因为我们没有传入 类初始不用传参,是利用装饰器使得类加了属性
let dog:any = new Animal()

console.log(dog.name)        // xxl
console.log(dog.getUrl())   // xxl123

装饰器的执行顺序

  1. 有多个参数装饰器时,从最后一个参数依次向前执行
  2. 方法和方法参数中参数装饰器先执行
  3. 类装饰器总是最后执行
  4. 方法和属性装饰器,谁在前面谁先执行。因为参数属于方法一部分,所以参数会一直紧紧挨着方法执行