什么是装饰器?它们在 JavaScript 中如何使用?

javascriptweb developmentfront end technology

在本教程中,您将了解 JavaScript 装饰器并了解其内部工作原理和用途。

什么是 JavaScript 中的装饰器?

装饰器一词的意思是将一组代码或程序与另一组代码或程序组合在一起,或者可以说是将一个函数与另一个函数包装在一起,以扩展该函数的功能或工作。装饰器也可以称为装饰器函数。

开发人员一直在其他语言(如 Python、C#)中使用这个装饰器术语,现在 JavaScript 也引入了装饰器。

函数装饰器

在 JavaScript 中,函数的行为类似于对象,因此它们也被称为一等对象,这是因为我们可以将函数分配给变量或从函数返回函数,或者可以将函数作为参数传递给函数。

示例

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

示例 

将函数传递给另一个函数

// MainFunction 函数将函数作为参数
function MainFunction(func) {
   func()
   console.log("Main function")
}

// 将函数分配给变量
var arrayFunction = function() {
    console.log("passed function")
}

//将argumentFunction函数传递给MainFunction
MainFunction(argumentFunction)

示例 

通过另一个函数返回一个函数

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

高阶函数

高阶函数是将函数作为参数并在执行某些操作后返回该函数的函数。上面讨论的函数是一个高阶函数,即printAdditionFunc

示例 

// 高阶函数
   function PrintName(name) {
      return function () {
         console.log("My name is ", name);
      }
   }
   
// output1 是一个函数,PrintName 返回一个函数
var output1 = PrintName("Kalyan")
output1()

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

您可能认为我们已经将装饰器作为高阶函数,那么为什么我们还需要单独的装饰器呢?

因此,我们有函数装饰器,它是高阶 JavaScript 函数,但是当类出现在 JavaScript 中时,我们在类中也有函数,其中高阶函数变得失败,就像装饰器一样。

示例 

让我们看看类的高阶函数的问题 -

// higher 是一个装饰器函数
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")
// 将类方法 websiteName 传递给高阶函数
var PrintName = higher(ob1.websiteName)
PrintName()

这里发生的情况是,当调用 higher 函数时,它会调用其参数,该参数是类的成员函数,即此处的 websiteName 函数。由于函数 websiteName 是从类函数外部调用的,因此 this 的值在 websiteName 函数内部未定义。所以,这就是此日志错误背后的原因。

因此,为了解决这个问题,我们还将传递 Website 类的对象,该对象最终将保留 this 的值。

//higher 是一个装饰器函数
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")
//将类方法 websiteName 传递给高阶函数
var PrintName = higher(ob1, ob1.websiteName)
PrintName()

在 PrintName 函数中,我们通过 call 函数调用 arg(这是一个 websiteName 函数),该函数通过 Website 类对象调用 websiteName 函数,因此此指针的值将是 Website 类的对象,并且具有 fname 和 lname 两个变量,因此它将正常工作而不会出现任何错误。

希望您通过本文了解装饰器及其用途。


相关文章