TypeScript-访问器装饰器

访问器装饰器概述

  • 访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)
  • 访问器装饰器应用于访问器的属性描述符并且可以用来监视,修改或替换一个访问器的定义

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

  • 对于静态方法而言就是当前的类, 对于实例方法而言就是当前的实例

  • 成员的名字

  • 成员的属性描述符

对于静态方法而言就是当前的类, 对于实例方法而言就是当前的实例:

实例方法:

function test(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(target);
    console.log(propertyKey);
    console.log(descriptor);
}

class Person {
    private _name: string;

    constructor(name: string) {
        this._name = name;
    }

    @test
    get name(): string {
        return this._name;
    }

    set name(value: string) {
        this._name = value;
    }
}

image-20211206131042305

静态方法略

注意点

  • TypeScript 不允许同时装饰一个成员的 getset 访问器
  • 取而代之的是,一个成员的所有装饰的必须应用在文档顺序的第一个访问器上

接下来先来看一个替换 set 方法的案例然后在来解释 TypeScript 不允许同时装饰一个成员的get和set访问器 这句话的含义,替换代码如下:

function test(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.set = (value: string) => {
        target.myName = "JonathanLee";
    }
}

class Person {
    private _name: string;

    constructor(name: string) {
        this._name = name;
    }

    get name(): string {
        return this._name;
    }

    @test
    set name(value: string) {
        this._name = value;
    }
}

let p = new Person('BNTang');
p.name = 'zs';
console.log(p.name);
console.log(p);

如上的代码含义为,我创建了一个 Person 对象然后重新设置了 name 但是 set 方法已经被我通过访问器装饰器给替换了,替换之后的 set 方法呢在实例上面添加了一个 myName 的属性所以浏览器当中依然会输出 BNTang 如下:

image-20211206132307264

通过如上的案例演示之后其实在访问器装饰器当中不仅仅可以拿到 set 其实 get 也是可以拿到的这就是如上我为什么说 TypeScript 不允许同时装饰一个成员的get和set访问器 的原因因为你只需要修饰其中一个另一个就可以直接拿到就没必须一一修饰了,然后我们在紧接着如上的案例来把 get 也替换一下看看如下:

function test(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.set = (value: string) => {
        target.myName = "JonathanLee";
    }
    descriptor.get = (): string => {
        return target.myName;
    }
}

class Person {
    private _name: string;

    constructor(name: string) {
        this._name = name;
    }

    get name(): string {
        return this._name;
    }

    @test
    set name(value: string) {
        this._name = value;
    }
}

let p = new Person('BNTang');
p.name = 'zs';
console.log(p.name);
console.log(p);

image-20211206132525490

posted @ 2021-12-06 13:27  BNTang  阅读(128)  评论(0编辑  收藏  举报