如何在 TypeScript 中使用屬性裝飾器?


裝飾器TypeScript中具有對類定義過程的程式設計訪問許可權。

請記住,類描述列出了類的屬性、指定的方法和結構。建立類例項時,該類例項可以訪問這些屬性和方法。但是,在建立類例項之前,裝飾器允許我們在類的定義中新增程式碼。它們等同於 C# 屬性或 Java 註解。

裝飾器是一個具有特定引數集的函式。JavaScript 執行時會自動填充這些引數,這些引數提供有關已應用裝飾器的類、方法或屬性的資訊。引數的型別和數量決定了裝飾器可以在哪裡使用。

裝飾器是 TypeScript 編譯器的實驗性功能,從 ES5 開始支援。要使用裝飾器,必須在 tsconfig.json 檔案中啟用編譯選項。該選項的名稱為 ExperimentalDecorators,需要將其設定為 true。

裝飾器允許透過用適當的功能和值封裝現有程式碼來進行修改。目前僅支援一個類及其部分 -

  • 類本身
  • 類方法
  • 類屬性
  • 類的物件訪問器(getter 和 setter)
  • 類方法引數

我們將只關注類屬性。

TypeScript 中的屬性裝飾器

屬性裝飾器是在屬性宣告之前宣告的。宣告檔案或環境上下文無法使用屬性裝飾器(例如在 declare class 中)。相反,使用稱為屬性裝飾器的函式來裝飾我們類中的屬性宣告。

有了這些知識,我們可以做一些有趣的事情,例如更改預設定義或透過新增新屬性或更改資料來修改我們的物件例項。它接收類的建構函式和屬性名稱作為引數。

使用屬性裝飾器

在執行時將屬性裝飾器表示式作為函式呼叫時,將向其傳遞以下兩個引數 -

  • 例項成員的類原型或靜態成員的類建構函式方法。
  • 成員的名稱。

語法

使用者可以按照以下語法在 TypeScript 中建立屬性裝飾器

//syntax to create decorator
Class Class_Name{
   @Decorator_Name(argument)
   // Code of Components 
}

如上語法所示,我們將在類中建立裝飾器的名稱和引數值。

示例

首先,我們建立一個名為“Person”的類。此類有兩個屬性,username 和 greet,我們將其記錄到控制檯。我們將使用裝飾器透過新增引數中提供的傳送者姓名來修改 username 屬性。請參見下面的類 -

class Person {
	@UpdatedMessage("ABC")
	username: string;
	greet: string;
}

對於Person類的username屬性,我們在此例項中使用了裝飾器UpdatedMessage。它將在執行時使用提供的引數呼叫 UpdatedMessage 函式。它應該生成一個函式來操作 username 屬性。我們返回的函式需要兩個引數。當我們想要獲取 username 或將 username 設定為新值時,將觸發 getter 和 setter 函式。

然後將使用 Object.defineProperty 函式。它用於為專案提供特定屬性。

有三個要求 -

  • 物件的例項 - 將新增屬性的物件。在我們的場景中,target 變數包含 Greeter 類的例項。

  • propertyName - 屬性的名稱。

  • 配置物件 - 它是一個具有定義屬性的專案。在我們的示例中,我們將 getter 和 setter 函式作為規範新增。

此函式將用 updatedMessage 替換當前的 username 屬性。現在我們將結合所有步驟,裝飾器就可以使用了。請參見以下程式碼 -

function UpdatedMessage(sender: string) {
   return function (target: any, propertyKey: string){
      let updatedmessage: string
      // Return modifiedMessage whenever the message is asked
      const getter = function () {
         return updatedmessage
      }
      // Set the modifiedMessage value
      const setter = function () {
         updatedmessage = `Hi ${sender}!`
      }

      // Overwrite the original message with modifiedMessage we just created
      Object.defineProperty(target, propertyKey, {
         get: getter,
         set: setter,
      })
   }
}

class Person {
   // Modify message property using decorator
   @UpdatedMessage('ABC')
   username: string
   greet: string
   constructor() {
      this.username = 'Hi there!'
      this.greet = 'Welcome to tutorialsPoint'
   }

   message() {
      console.log(`${this.username}`)
      console.log(`${this.greet}`)
   }
}
let Greetings = new Person()
Greetings.message()

編譯後,它將生成以下 JavaScript 程式碼 -

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
   var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
   if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
   else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
   return c > 3 && r && Object.defineProperty(target, key, r), r;
};
function UpdatedMessage(sender) {
   return function (target, propertyKey) {
      var updatedmessage;
      // Return modifiedMessage whenever the message is asked
      var getter = function () {
         return updatedmessage;
      };
      // Set the modifiedMessage value
      var setter = function () {
         updatedmessage = "Hi " + sender + "!";
      };
      // Overwrite the original message with modifiedMessage we just created
      Object.defineProperty(target, propertyKey, {
         get: getter,
         set: setter
      });
   };
}
var Person = /** @class */ (function () {
   function Person() {
      this.username = 'Hi there!';
      this.greet = 'Welcome to tutorialsPoint';
   }
   Person.prototype.message = function () {
      console.log("" + this.username);
      console.log("" + this.greet);
   };
   __decorate([
      UpdatedMessage('ABC')
   ], Person.prototype, "username");
   return Person;
}());
var Greetings = new Person();
Greetings.message(); 

輸出

以上程式碼將產生以下輸出 -

Hi ABC!
Welcome to tutorialsPoint

因此,我們看到我們可以在類的屬性上使用裝飾器並對其進行操作。裝飾器幫助我們建立更易讀和靈活的程式碼。

更新於:2022-12-19

3K+ 閱讀量

開啟你的職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.