返回

揭秘 JavaScript 装饰器的原理与应用

前端

JavaScript 装饰器的基本原理

JavaScript 装饰器本质上是一个函数,它接受一个类或函数作为参数,并返回一个新的类或函数。这个新的类或函数具有增强后的行为或特性,而无需修改原始的代码。

function decorator(target) {
  // 对目标类或函数进行装饰
  // 返回一个新的类或函数
}

@decorator
class MyClass {
  // 类的方法和属性
}

// MyClass现在具有decorator装饰后的行为

函数装饰器

函数装饰器用于装饰函数,它可以在函数执行前后或函数返回结果之前做一些事情。例如,我们可以使用函数装饰器来记录函数的执行时间或对函数的参数进行校验。

function timingDecorator(target, key, descriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function (...args) {
    const start = performance.now();
    const result = originalMethod.apply(this, args);
    const end = performance.now();
    console.log(`Function ${key} took ${end - start} milliseconds to execute.`);
    return result;
  };
}

class MyClass {
  @timingDecorator
  calculateSomething(n) {
    // 复杂的计算逻辑
  }
}

const instance = new MyClass();
instance.calculateSomething(10000);
// 控制台输出:Function calculateSomething took 123.456 milliseconds to execute.

类装饰器

类装饰器用于装饰类,它可以在类实例化之前或之后做一些事情。例如,我们可以使用类装饰器来验证类的属性或为类添加新的方法。

function classDecorator(target) {
  // 对目标类进行装饰

  // 修改或扩展类的原型
  target.prototype.newMethod = function () {
    // 新方法的实现
  };
}

@classDecorator
class MyClass {
  // 类的属性和方法
}

const instance = new MyClass();
instance.newMethod(); // 调用新添加的方法

装饰器设计模式

装饰器不仅可以用于添加新的行为或特性,还可以用于实现设计模式。例如,我们可以使用装饰器来实现单例模式、代理模式和观察者模式等。

// 单例模式
function singletonDecorator(target) {
  let instance;

  return class {
    constructor() {
      if (!instance) {
        instance = new target();
      }

      return instance;
    }
  };
}

@singletonDecorator
class MySingleton {
  // 单例类的属性和方法
}

const instance1 = new MySingleton();
const instance2 = new MySingleton();

console.log(instance1 === instance2); // true

结语

JavaScript 装饰器是一种强大的工具,它可以让我们在不修改源代码的情况下扩展类或函数的行为。通过使用装饰器,我们可以更轻松地实现各种设计模式,并使我们的代码更具可扩展性和可维护性。