从前有匹马叫代码
心若没有栖息的地方,到哪里都是流浪

装饰器在 TS 中是一个实验性的特性,需要在tsconfig.json中将 experimentalDecorators 设置为true来禁止警告。

那什么是装饰器呢?按照Learning Typescript中的说法就是

A class decorator is just a function that takes the class as its only argument and returns it after doing something with it

说白了意思就是,装饰器就是一个函数,然后在使用时候会将被装饰的类作为参数传递到函数内,然后你就可以想干啥干啥了。

直接上代码:

function addMetadata(target: any) {
    target.__customMetadata = {
        somekey: "value",
    };
    return target;
}

@addMetadata
class Person {
    private _name: string;
    public constructor(name: string) {
        this._name = name;
    }

    public greet() {
        return this._name;
    }
}

function getMetadataFromInstance(target: any) {
    return target.constructor.__customMetadata;
}

let person1 = new Person("John");
let person2 = new Person("Lisa");
console.log(getMetadataFromInstance(person1)); // { somekey: 'value' }
console.log(getMetadataFromInstance(person2)); // { somekey: 'value' }

需要注意的一点是 在声明类时应用装饰器,而不是在创建类的实例时应用。这意味着元数据在类的所有实例中共享:

let person1 = new Person("John");
let person2 = new Person("Lisa");
console.log(getMetadataFromInstance(person1) === getMetadataFromInstance(person2)); // true

如何给装饰器传参数?
我们可以在装饰器函数中返回一个匿名函数来实现,具体代码如下

function addMetadata(max: number) {
    return function (target: any) {
        target._random = Math.floor(Math.random() * max);
    };
}

@addMetadata(10)
class Person {
    private _name: string;
    public constructor(name: string) {
        this._name = name;
    }
    public greet() {
        return this._name;
    }
}

function getMetadataFromClass(target: any) {
    return target.constructor._random;
}

const person = new Person("随机数");


console.log(getMetadataFromClass(person)) // 6

posted on 2021-08-25 23:04  从前有匹马叫代码  阅读(89)  评论(0编辑  收藏  举报