引讀:爲何要寫裝飾器這篇文章了,裝飾器給人感受很NB的樣子,不少同窗對裝飾器的用法仍是很模糊,文檔又讓他們很難徹底理解;但願讀了這篇博客之後,能對裝飾器有不同的理解;api
// 類裝飾器:普通裝飾器(沒法傳參) function logClass(params){ // params 就是當前類 console.log(params) params.prototype.apiUrl = "動態擴展的屬性" params.prototype.fetch = function(){ console.log('我是一個fetch方法') } } @logClass class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // 動態擴展的屬性 http.fetch() // 我是一個fetch方法
// 類裝飾器:裝飾器工廠(能夠傳參) function logClass(params){ console.log(params) // params調用時的實參 return function(target){ // target 當前類 HttpClient console.log(target) params.prototype.apiUrl = params } } @logClass('newbanker') class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // newbanker
// 裝飾器能夠修改當前類的構造函數和方法 // 類裝飾器表達式會在運行時當作函數被調用,類的構造函數做爲其惟一參數 // 若是類裝飾器返回一個值,它會使用提供的構造函數來替換類的聲明 // 下面是一個函數重載的例子 function logClass(params){ console.log(params) // params調用時的實參 return class extends target { apiUrl = "我是修改後的數據" getData(){ console.log(this.apiUrl+'------') } } } @logClass class HttpClient { constructor(){ this.apiUrl = "我是構造函數裏面的apiUrl" }
// 類裝飾器:普通裝飾器(沒法傳參) function logClass(params){ // params 就是當前類 console.log(params) params.prototype.apiUrl = "動態擴展的屬性" params.prototype.fetch = function(){ console.log('我是一個fetch方法') } } @logClass class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // 動態擴展的屬性 http.fetch() // 我是一個fetch方法
// 類裝飾器:裝飾器工廠(能夠傳參) function logClass(params){ console.log(params) // params調用時的實參 return function(target){ // target 當前類 HttpClient console.log(target) params.prototype.apiUrl = params } } @logClass('newbanker') class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // newbanker
// 裝飾器能夠修改當前類的構造函數和方法 // 類裝飾器表達式會在運行時當作函數被調用,類的構造函數做爲其惟一參數 // 若是類裝飾器返回一個值,它會使用提供的構造函數來替換類的聲明 // 下面是一個函數重載的例子 function logClass(params){ console.log(params) // params調用時的實參 return class extends target { apiUrl = "我是修改後的數據" getData(){ console.log(this.apiUrl+'------') } } } @logClass class HttpClient { constructor(){ this.apiUrl = "我是構造函數裏面的apiUrl" } getData(){ console.log(this.apiUrl) } } let http = new HttpClient() console.log(http.apiUrl) // 我是修改後的數據
// 類裝飾器:裝飾器工廠(能夠傳參) function logClass(params){ console.log(params) // params調用時的實參 return function(target){ // target 當前類 HttpClient console.log(target) } } // 屬性裝飾器 function logProperty(params){ return function(target, attr){ console.log(target) // console.log(attr) // 當前屬性url target.attr = params } } @logClass class HttpClient { @logProperty('https://baidu.com') public url getData(){ } }
// 方法裝飾器 function logMethod(params){ return function(target, methodName, desc){ console.log(target) // 原型對象,能夠擴展類的原型屬性和方法; // 能夠擴展當前實例的屬性和方法 target.apiUrl = "http://www.sina.cn" target.run = function(){ console.log('run') } console.log(methodName) // 當前方法名 getData // 修改裝飾器的方法,把裝飾器方法裏面傳入的全部參數改成string類型; // 保存當前方法 let save = desc.value desc.value = function(...args){ args.map((v) => { return String(v) }) console.log(v) } console.log(desc) // 描述信息 { value: f, xxx: xxx } // 不加此方法會直接替換實例的方法,加上會修改 save.apply(this, args) // 把當前方法this傳進去,表明在這個方法裏面調用save方法;並傳入參數; } } class HttpClient { public url: any | undefind; constructor(){ } @get('http://www.baidu.com') getData(args){ console.log(args) // ['123', 'string'] console.log('我是getData的method') } } let http = new HttpClient(); console.log(http.apiUrl) // http://www.sina.cn http.getData(123, 'string')
// 方法參數裝飾器 function logParams(params){ return function(target, paramsName, paramsIndex){ console.log(params) // xxxx console.log(target) // console.log(paramsName) // getData console.log(paramsIndex) // 0 } } class HttpClient { getData(@logParams1('xxxx') uuid: any, @logParams2('xxxx') name: any){ console.log(uuid) // 123 } } let http: any = new HttpClient(); http.getData(123)
@logClass1('http:www.baidu.con') @logClass2('xxxx') class HttpClient { @logAttribute() public apiUrl: string | undefind constructor(){ } @logMethod() getData(){ } setData(@logParams1() attr1: any, @logParams2() attr2: any){ } } let http: any = new HttpClient(); // 屬性裝飾器 > 方法裝飾器 > 方法參數裝飾器2 > 方法參數裝飾器1 > 類裝飾器2 > 類裝飾器1