当前位置:首页 > JavaScript

js 实现装饰器

2026-04-07 10:53:21JavaScript

装饰器基础概念

装饰器是一种特殊类型的声明,能够附加到类声明、方法、属性或参数上,以修改或扩展其行为。在 JavaScript 中,装饰器通过 @ 符号前缀使用,本质上是高阶函数。

环境配置

装饰器目前处于提案阶段(Stage 3),需通过 Babel 或 TypeScript 编译支持:

  1. Babel 配置:安装 @babel/plugin-proposal-decorators 插件并启用 legacy: true
  2. TypeScript:在 tsconfig.json 中设置 "experimentalDecorators": true

类装饰器

类装饰器接收目标类的构造函数作为参数,可用于修改或替换类定义:

js 实现装饰器

function logClass(target) {
  console.log(`Class ${target.name} decorated`);
  return class extends target {
    constructor(...args) {
      super(...args);
      console.log('Instance created');
    }
  };
}

@logClass
class MyClass {}
new MyClass(); // 输出: "Class MyClass decorated" 和 "Instance created"

方法装饰器

方法装饰器接收三个参数:目标类原型、方法名、属性描述符。常用于拦截或增强方法逻辑:

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

class Calculator {
  @logMethod
  add(a, b) {
    return a + b;
  }
}
new Calculator().add(2, 3); // 输出: "Calling add with args: [2, 3]"

属性装饰器

属性装饰器接收目标类原型和属性名,常用于标记或修改属性:

js 实现装饰器

function readonly(target, key) {
  Object.defineProperty(target, key, { writable: false });
}

class User {
  @readonly
  name = 'Alice';
}
const user = new User();
user.name = 'Bob'; // 报错: Cannot assign to read only property

参数装饰器

参数装饰器接收目标类原型、方法名和参数索引,通常用于依赖注入或参数验证:

function validateParam(target, methodName, paramIndex) {
  console.log(`Validating parameter ${paramIndex} of ${methodName}`);
}

class ApiService {
  fetchData(@validateParam id) {
    return { data: `ID: ${id}` };
  }
}
new ApiService().fetchData(123); // 输出: "Validating parameter 0 of fetchData"

装饰器工厂

通过高阶函数生成可配置的装饰器:

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

class Task {
  @delay(1000)
  run() {
    console.log('Task executed after 1s');
  }
}
new Task().run(); // 1秒后输出

注意事项

  1. 装饰器执行顺序:属性/方法/参数装饰器从右到左,类装饰器最后执行。
  2. 避免在装饰器中直接修改原型链,可能导致不可预期行为。
  3. 生产环境需确保编译工具链支持装饰器语法。

标签: js
分享给朋友:

相关文章

js实现vue

js实现vue

Vue.js 简介 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。其核心库专注于视图层,易于与其他库或现有项目整合。 实现 Vue.js 的基本步骤 安装 Vue.j…

js实现

js实现

实现 JavaScript 功能的方法 在 JavaScript 中实现特定功能通常涉及多个步骤。以下是常见的实现方法: 基础语法和变量声明 使用 let 或 const 声明变量: let co…

js实现计算器

js实现计算器

实现基础计算器功能 使用JavaScript创建一个基础计算器需要处理数字输入、运算符逻辑和结果显示。以下是一个简单的实现示例: let currentInput = '0'; let previo…

js 实现倒计时

js 实现倒计时

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

js实现选项卡

js实现选项卡

实现选项卡的基本思路 选项卡通常由一组标签和对应的内容面板组成。点击标签时,显示对应的内容面板,隐藏其他面板。实现这一效果需要结合HTML结构、CSS样式和JavaScript交互逻辑。 HTML结…

js实现tab选项卡切换

js实现tab选项卡切换

实现Tab选项卡切换的JavaScript方法 使用纯JavaScript实现Tab切换功能,可以通过监听点击事件动态切换内容显示状态。以下是两种常见实现方式: 基础DOM操作实现 /…