TS进阶(一)装饰器

装饰器

在一些场景我们需要额外的特性来支持标注或者修改类及其成员的时候,装饰器为我们在类及其远程通过元编译语法添加标注提供一种方法。

格式

@func ():@加上函数名称()
注意:在TS中,目前只是在试验阶段,需要在tsconfig.json里启用experimentalDecorators编译器

{
    "compilerOptions": {
        "target": "ES5",
        "experimentalDecorators": true
    }
}

装饰器装饰方法

function f(){
    console.log("f meth");
    return function(target:any,propertyKey:string,descriptor:PropertyDescriptor):void{
        let value = descriptor.value;
        console.log("propertyKey:" +propertyKey);
        console.log("target:",target[propertyKey](1,2,3));
        
        // descriptor.value = function(){
        //     // console.log("f() call",value)
        //     value.call(this,...arguments);
        // }
       
    }
}
    class A {
        @f()
        test(...data:any):void{
            console.log(data)
        }
    }
    let a :A  = new A();
    a.test(1,"2",3)

装饰器装饰方法:当方法被调用的时候,不会指定函数体代码,而是执行装饰器里面的代码。函数装饰器包含三个参数。第一个target 表示源对象及 a对象,第二个参数表示属性的名称:test,第三个参数表示属性的可操作性,比如write(可写),value:属性的值,....类型为PropertyDescriptor

装饰器装饰类

装饰器可以装饰整个类,当是装饰类的时候,我们new一个对象,会执行装饰器里面的代码

 interface A {
        x:number,
        y:number
    }
    function testA(target:any){
        console.log("dddddddddddd");
        target.prototype.x = 1
        target.prototype.y = 1
        // target 为A构造函数
    }
    @testA
    class A {
        constructor(){

        }
    }
    let a:A = new A();
    console.log(a.x,a.y);

其中target代表的是类的构造函数

装饰类2

装饰类返回一个新的对象

  interface A {
        x:number,
        y:number,
        age:number
    }
    function testA(target:Function):any{
        console.log("dddddddddddd");
        // console.log(target);
        // target()
        target.prototype.x = 1
        target.prototype.y = 1
    return class {
}
      //  return  target()
        // target 为A构造函数
    }
    @testA
    class A {
        constructor(public name:number){
            console.log('constructor');
            
        }
    }
    let a:A = new A(3);
    console.log(a);

这个类似于JavaScript类似,当构造函数可以返回一个对象,也可以返回一个自定义对象

装饰器参数

装饰器函数课传递参数

class Point {
    private _x: number;
    private _y: number;
    constructor(x: number, y: number) {
        this._x = x;
        this._y = y;
    }

    @configurable(false)
    get x() { return this._x; }

    @configurable(false)
    get y() { return this._y; }
}
function configurable(value: boolean) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        descriptor.configurable = value;
    };
}

推荐阅读更多精彩内容