返回

JS装饰器,一文洞悉

前端

装饰器的基本原理

装饰器本质上是一种高阶函数。它可以接收一个函数作为参数,并返回一个新的函数,该函数的行为通常与传入的函数类似,但也可能对其进行某些增强或修改。装饰器的语法也非常简单,它通常是一个紧跟在函数或类之前的@符号,后面接着装饰器函数的名称。

装饰器主要分为函数装饰器和类装饰器两种,其使用场景略有差异:

函数装饰器

函数装饰器用于对函数进行修饰和扩展。它可以用来实现诸如计时、日志记录和缓存等功能。下面是一个简单的例子:

function log(target, name, descriptor) {
  const oldValue = descriptor.value;
  descriptor.value = function () {
    console.log(`Calling ${name} with args ${arguments}`);
    return oldValue.apply(this, arguments);
  };
  return descriptor;
}

@log
function sayHello(name) {
  console.log(`Hello ${name}!`);
}

sayHello("John"); // Calling sayHello with args (John)
// Hello John!

在上面的例子中,我们使用log装饰器来记录sayHello函数的调用信息。当sayHello函数被调用时,装饰器会在其前后分别输出调用信息和函数的返回值。

类装饰器

类装饰器用于对类进行修饰和扩展。它可以用来实现诸如添加属性、修改方法行为和拦截类构造器等功能。下面是一个简单的例子:

function sealed(target) {
  Object.seal(target);
}

@sealed
class MyClass {
  constructor() {
    this.prop1 = "Hello";
  }

  greet() {
    console.log(`Hello ${this.prop1}!`);
  }
}

const instance = new MyClass();
instance.prop1 = "World"; // TypeError: Cannot assign to read only property 'prop1' of object '[object Object]'

在上面的例子中,我们使用sealed装饰器来密封MyClass类。当密封一个类时,它的属性和方法将被冻结,从而防止它们被修改或扩展。

装饰器的优缺点

装饰器是一种强大的工具,它可以帮助我们对函数和类进行扩展和修饰,并使我们的代码更具有可重用性和可维护性。然而,装饰器也有一些缺点:

  • 增加代码复杂性:装饰器会使代码更加复杂和难以理解,尤其是当多个装饰器被应用到同一个函数或类时。
  • 性能开销:装饰器可能会带来一些额外的性能开销,因为它们需要在运行时被执行。

总结

装饰器是一种用于修饰和扩展JavaScript函数和类的语法糖。它可以用来实现诸如计时、日志记录和缓存等功能。装饰器分为函数装饰器和类装饰器两种,其使用场景略有差异。函数装饰器用于对函数进行修饰和扩展,而类装饰器用于对类进行修饰和扩展。装饰器可以帮助我们对函数和类进行扩展和修饰,并使我们的代码更具有可重用性和可维护性。