typescript - 9.裝飾器

裝飾器:裝飾器是一種特殊類型的聲明,它可以被附加到類聲明,方法,屬性或參數上,能夠修改類的行爲。typescript

通俗的講裝飾器就是一個方法,能夠注入到類、方法、屬性參數上來擴展類、屬性、方法、參數的功能。api

常見的裝飾器有:app

  • 類裝飾器
  • 屬性裝飾器
  • 方法裝飾器
  • 參數裝飾器

裝飾器的寫法:函數

  • 普通裝飾器(沒法傳參)
  • 裝飾器工廠(可傳參)

裝飾器是過去幾年中js最大的成就之一,已經是Es7的標準特性之一this

類裝飾器

普通裝飾器(沒法傳參)

function logClass(params:any){

            console.log(params);
            // params 就是當前類
            params.prototype.apiUrl='動態擴展的屬性';
            params.prototype.run=function(){
                console.log('我是一個run方法');
            }

        }

        @logClass
        class HttpClient{
            constructor(){
            }
            getData(){

            }
        }
        var http:any=new HttpClient();
        console.log(http.apiUrl);  //動態擴展的屬性
        http.run();     //我是一個run方法

裝飾器工廠(可傳參)

function logClass(params:string){
            return function(target:any){
                console.log(target);  //當前類:HttpClient
                console.log(params);    //http://www.itying.com/api
                target.prototype.apiUrl=params;
            }
        }

        @logClass('http://www.itying.com/api')
        class HttpClient{
            constructor(){
            }

            getData(){

            }
        }

        var http:any=new HttpClient();
        console.log(http.apiUrl);

屬性裝飾器

屬性裝飾器表達式會在運行時看成函數被調用,傳入下列2個參數:
一、對於靜態成員來講是類的構造函數,對於實例成員是類的原型對象。
二、成員的名字。url

//類裝飾器
    function logClass(params:string){
        return function(target:any){
            // console.log(target);
            // console.log(params);       
            
        }
    }

//屬性裝飾器
function logProperty(params: any) {
    return function (target: any, attr: any) {
        console.log(target);
        console.log(attr);
        target[attr] = params;
    }
}
@logClass('xxxx')

class HttpClient {

    @logProperty('監視屬性')
    public url: any | undefined;

    constructor() {
    }
    
    getData() {
        console.log(this.url);
    }
}
var http = new HttpClient();
http.getData();

方法裝飾器

它會被應用到方法的 屬性描述符上,能夠用來監視,修改或者替換方法定義。prototype

方法裝飾會在運行時傳入下列3個參數:
一、對於靜態成員來講是類的構造函數,對於實例成員是類的原型對象。
二、成員的名字。
三、成員的屬性描述符。code

擴展方法

正常的擴展方法.對象

function get(params:any){
   
    return function(target:any,methodName:any,desc:any){
        console.log(`0.params${params}`);
        console.log(`1.target:`);
        console.log(target);
        console.log("2.methodName:");
        console.log(methodName);
        console.log("3.desc:");
        console.log(desc);
        target.Apiurl='xxxx';
        target.run=function(){
            console.log('5.run');
        }
    }
}

class HttpClient{  
    public url:any |undefined;

    constructor(){
    }

    @get('param參數在這裏~~~')
    getData(){
        console.log("6.this.url");
        console.log(this.url);
    }
}

var http:any=new HttpClient();
console.log("4.http.Apiurl");
console.log(http.Apiurl);
http.run();
http.getData();

修改方法內容

function get(params:any){
   
    return function(target:any,methodName:any,desc:any){
        // console.log(`0.params${params}`);
        // console.log(`1.target:`);
        // console.log(target);
        // console.log("2.methodName:");
        // console.log(methodName);
        // console.log("3.desc:");
        // console.log(desc);
        
        //修改裝飾器的方法  把裝飾器方法裏面傳入的全部參數改成string類型

        let oMethod = desc.value;
        desc.value = function name(...args:any[]) {
            args = args.map(value=>{
                return String(value);
            })
            
            oMethod.apply(this,args);
            console.log(args);
        }
    }
}

class HttpClient{  
    public url:any |undefined;

    constructor(){
    }

    @get('param參數在這裏~~~')
    getData(){
        console.log("這裏是getData方法內~");
    }
}

var http:any=new HttpClient();
http.getData(123,"aabb");

相關文章
相關標籤/搜索