什麼是裝飾器以及如何在 JavaScript 中使用它們?


在本教程中,您將瞭解 JavaScript 裝飾器,並瞭解其內部工作原理和用途。

什麼是 JavaScript 裝飾器?

裝飾器一詞意味著將一組程式碼或程式與另一個程式碼或程式組合,或者可以將其描述為用另一個函式包裝一個函式以擴充套件函式的功能或工作方式。裝飾器也可以稱為裝飾器函式。

開發人員一直在其他語言(如 python、C#)中使用這個裝飾器術語,現在 JavaScript 也引入了裝飾器。

函式裝飾器

在 JavaScript 中,函式的行為類似於物件,因此它們也被稱為一等物件,這是因為我們可以將函式分配給變數,或者從函式返回函式,或者可以將函式作為引數傳遞給函式。

示例

const func_variable= function(){
   console.log("Hey there");
}
func_variable()

示例

將函式傳遞給另一個函式

// MainFunction function takes a function as a parameter
function MainFunction(func) {
   func()
   console.log("Main function")
}

// Assigning function to a variable
var argumentFunction = function() {
   console.log("passed function")
}

//passing argumentFunction function to to MainFunction
MainFunction(argumentFunction)

示例

由另一個函式返回函式

function SumElement(par1, par2) {
   var addNumbers = function () {
      result = par1+par2;
      console.log("Sum is:", result);
   }
   
   // Returns the addNumbers function
   return addNumbers
}
var PrintElement = SumElement(3, 4)
console.log(PrintElement);
PrintElement()

高階函式

高階函式是指將函式作為引數,並在執行某些操作後返回該函式的函式。上面討論的函式 printAdditionFunc 就是一個高階函式。

示例

// higher order function
   function PrintName(name) {
      return function () {
         console.log("My name is ", name);
      }
   }
   
// output1 is a function, PrintName returns a function
var output1 = PrintName("Kalyan")
output1()

var output2= PrintName("Ashish")
output2()

您可能在想,既然我們已經有高階函式作為裝飾器,為什麼還需要單獨的裝飾器呢?

因此,我們有作為高階 JavaScript 函式的函式裝飾器,但是當 JavaScript 中出現類時,我們也在類中有了函式,而充當裝飾器的高階函式在這裡失效了。

示例

讓我們看看類中高階函式的問題 -

// higher is a decorator function
function higher(arg) {
   return function() {
      console.log("First "+ arg.name)
      arg() // Decorator function call
      console.log("Last " + arg.name)
   }
}
class Website {
   constructor(fname, lname) {
      this.fname = fname
      this.lname = lname
   }
   websiteName() {
      return this.fname + " " + this.lname
   }
}
var ob1 = new Website("Tutorials", "Point")
// Passing the class method websiteName to the higher order function
var PrintName = higher(ob1.websiteName)
PrintName()

這裡發生的情況是,當呼叫高階函式時,它會呼叫其引數,即此處作為類成員函式的 websiteName 函式。由於函式 websiteName 是從類外部函式呼叫的,因此在 websiteName 函式內部,this 的值為 undefined。所以,這就是導致此日誌錯誤的原因。

因此,為了解決這個問題,我們還需要傳遞 **Website** 類的物件,這最終將保留 this 的值。

//higher is a decorator function
function higher(ob1, arg) {
   return function() {
      console.log("Execution of " + arg.name + " begin")
      arg.call(ob1) //// Decorator function call
      console.log("Execution of " + arg.name + " end")
   }
}
class Website {
   constructor(fname, lname) {
      this.fname = fname
      this.lname = lname
   }
   websiteName() {
      return this.fname + " " + this.lname
   }
}
var ob1 = new Website("Tutorials", "Point")
//Passing the class method websiteName to the higher order function
var PrintName = higher(ob1, ob1.websiteName)
PrintName()

這裡在 PrintName 函式內部,我們藉助 call 函式呼叫 arg(它是 websiteName 函式),該函數借助 Website 類物件呼叫 websiteName 函式,因此 this 指標的值將是 Website 類的物件,並且它同時具有 fname 和 lname 兩個變數,因此它將在沒有任何錯誤的情況下工作。

希望透過本文,您已經瞭解了裝飾器及其用途。

更新於:2022-12-01

945 次瀏覽

開啟您的 職業生涯

透過完成課程獲得認證

開始學習
廣告