当前位置:首页 > JavaScript

js怎么实现装饰器

2026-01-31 00:47:27JavaScript

装饰器基础概念

装饰器是一种特殊函数,用于修改类、方法或属性的行为。在JavaScript中,装饰器通过@符号调用,目前处于提案阶段(Stage 3),需通过Babel或TypeScript编译支持。

环境配置

使用装饰器需配置Babel或TypeScript:

  • Babel:安装@babel/plugin-proposal-decorators插件,配置.babelrc
    {
      "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }]
      ]
    }
  • TypeScript:在tsconfig.json中启用:
    {
      "compilerOptions": {
        "experimentalDecorators": true
      }
    }

类装饰器

类装饰器接收目标类构造函数,可扩展或修改类:

function logClass(target) {
  console.log(`Class ${target.name} decorated`);
  // 添加原型方法
  target.prototype.print = () => console.log('Decorated method');
}

@logClass
class MyClass {}
const instance = new MyClass();
instance.print(); // 输出: "Decorated method"

方法装饰器

方法装饰器接收三个参数:目标对象、方法名、属性描述符。常用于拦截方法调用:

function readonly(target, name, descriptor) {
  descriptor.writable = false;
  return descriptor;
}

class User {
  @readonly
  getName() { return 'John'; }
}

const user = new User();
user.getName = () => 'Hack'; // 报错:无法重写只读方法

属性装饰器

属性装饰器接收目标对象和属性名,常用于元数据标记:

function format(formatString) {
  return function (target, key) {
    Reflect.defineMetadata('format', formatString, target, key);
  };
}

class Book {
  @format('YYYY-MM-DD')
  publishDate = '2023-01-01';
}

// 通过反射获取元数据
const metadata = Reflect.getMetadata('format', Book.prototype, 'publishDate');
console.log(metadata); // 输出: "YYYY-MM-DD"

参数装饰器

参数装饰器用于标记方法参数,接收目标对象、方法名和参数索引:

function validate(type) {
  return function (target, key, index) {
    Reflect.defineMetadata('validate', { type, index }, target, key);
  };
}

class ApiService {
  fetch(@validate('number') id) {
    return { data: id };
  }
}

装饰器工厂

通过高阶函数实现可配置装饰器:

function delay(ms) {
  return function (target, key, descriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args) {
      setTimeout(() => originalMethod.apply(this, args), ms);
    };
    return descriptor;
  };
}

class Logger {
  @delay(1000)
  log(message) {
    console.log(message);
  }
}

const logger = new Logger();
logger.log('Delayed message'); // 1秒后输出

注意事项

  • 装饰器在类定义时执行,而非实例化时。
  • 装饰器不能用于函数(因存在函数提升)。
  • 第三方库如core-decorators提供常用装饰器(如@deprecated)。

通过组合不同类型的装饰器,可实现AOP(面向切面编程)、日志、权限控制等复杂功能。

js怎么实现装饰器

标签: js
分享给朋友:

相关文章

js实现跳转

js实现跳转

使用 window.location 跳转 通过修改 window.location.href 或直接使用 window.location 实现页面跳转,适用于普通跳转或带参数的 URL。 // 方…

js实现

js实现

JavaScript 实现方法 JavaScript 是一种广泛使用的编程语言,适用于网页开发、服务器端编程以及移动应用开发。以下是几种常见的 JavaScript 实现方法: 网页交互功能 使用…

js实现轮播

js实现轮播

实现基础轮播效果 使用HTML结构创建轮播容器和图片元素: <div class="carousel"> <div class="carousel-inner">…

js实现倒计时

js实现倒计时

实现倒计时的基本方法 使用 JavaScript 实现倒计时功能可以通过 setInterval 或 setTimeout 结合日期计算来完成。以下是几种常见的实现方式: 使用 setInterva…

js实现拖拽

js实现拖拽

实现拖拽的基本步骤 通过监听鼠标事件(mousedown、mousemove、mouseup)实现拖拽功能。以下是核心代码逻辑: const draggableElement = document.…

js实现图片轮播

js实现图片轮播

实现基础图片轮播 使用HTML、CSS和JavaScript创建一个简单的图片轮播。HTML部分定义轮播容器和图片,CSS设置样式和动画效果,JavaScript处理轮播逻辑。 <div c…