TS之裝飾器① 類裝飾器&屬性裝飾器


裝飾器:

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

  裝飾器使用 @expression這種形式,expression求值后必須為一個函數,它會在運行時被調用,被裝飾的聲明信息做為參數傳入。

常見的裝飾器有:

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

裝飾器的寫法:

  普通裝飾器(無法傳參)、裝飾器工廠(可傳參)

1.類裝飾器:

類裝飾器在類聲明之前被聲明(緊靠着類聲明)。類裝飾器應用於類構造函數,可以用來監視、修改或者 替換類定義。

(1)普通裝飾器

// 定義普通裝飾器
function logClass(params: any) {
  console.log(params);

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

// 使用類裝飾器(普通裝飾器,無法傳參)
@logClass
class HttpClient {
  constructor() {
  }

  getData() {
  }
}

let http = new HttpClient();

 (2)裝飾器工廠

// 定義裝飾器工廠
function logClass(params: string) {
  return function (target: any) {
    console.log('target:', target);
    console.log('params:', params);

    target.prototype.apiUrl = params;
  }
}

// 使用類裝飾器:裝飾器工廠,可傳參(相當於把hello給了params,下面這個類給了target)
@logClass('http:www.baidu.com')
class HttpClient {
  constructor() {
  }

  getData() {
  }
}

let http = new HttpClient();
console.log(http.apiUrl);

 

類裝飾器重載構造函數的例子:

  類裝飾器表達式會在運行時當作函數被調用,類的構造函數(constructor)作為其唯一的參數;如果類裝飾器返回一個值,它會使用提供的構造函數來替換類的聲明;

// 定義裝飾器工廠
function logClass(target: any) {
  console.log(target);

 // 把類的構造函數作為參數傳入,並修改構造函數
return class extends target { // 修改當前類的構造函數 apiUrl: any = "我是在裝飾器里面修改后的apiUrl" // 修改方法 getData() { this.apiUrl = this.apiUrl + '====='; console.log(this.apiUrl); } } } @logClass class HttpClient { public apiUrl: string | undefined; constructor() { this.apiUrl = "我是構造函數里面的apiUrl" } getData() { console.log(this.apiUrl); } } let http = new HttpClient(); http.getData();

 2.屬性裝飾器

  屬性裝飾器表達式會在運行時當作函數被調用,傳入下列兩個參數:

  • 對於靜態成員來說是類的構造函數,對於實例成員是類的原型對象
  • 成員的名字
// 定義類裝飾器
function logClass(params: string) {
  return function (target: any) {
    console.log(target);
    console.log(params);
  }
}

// 定義屬性裝飾器
function logProperty(params: any) {
  // target--->類的原型對象;attr--->傳入的參數url
  return function (target: any, attr: any) {
    console.log(target, attr);

    target[attr] = params
  }
}

@logClass('xxxx')
class HttpClient {

  @logProperty('http://www.baidu.com')
  public url: any | undefined;
  constructor() {

  }
  getData() {
    console.log(this.url);
  }
}

let http = new HttpClient();
http.getData();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM