当前位置:首页 > JavaScript

js 实现装饰器

2026-02-02 17:11:24JavaScript

装饰器的基本概念

装饰器是一种特殊类型的声明,能够附加到类、方法、属性或参数上,以修改或扩展其行为。在 JavaScript 中,装饰器目前处于提案阶段(Stage 3),需通过 Babel 或 TypeScript 等工具支持。

启用装饰器语法

在项目中使用装饰器前,需配置编译环境:

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

类装饰器

类装饰器应用于类构造函数,用于修改或替换类定义。

function logClass(target: Function) {
  console.log(`Class ${target.name} is decorated.`);
}

@logClass
class MyClass {}
// 输出:Class MyClass is decorated.

方法装饰器

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

function readonly(target: any, key: string, descriptor: PropertyDescriptor) {
  descriptor.writable = false;
  return descriptor;
}

class Example {
  @readonly
  method() {}
}

const obj = new Example();
obj.method = () => {}; // 报错:Cannot assign to read only property

属性装饰器

属性装饰器用于修饰类的属性,接收目标对象和属性名。

function logProperty(target: any, key: string) {
  let value = target[key];
  const getter = () => {
    console.log(`Get ${key} => ${value}`);
    return value;
  };
  const setter = (newVal: any) => {
    console.log(`Set ${key} => ${newVal}`);
    value = newVal;
  };
  Object.defineProperty(target, key, {
    get: getter,
    set: setter,
    enumerable: true,
    configurable: true
  });
}

class User {
  @logProperty
  name: string;
}

const user = new User();
user.name = 'Alice'; // 输出:Set name => Alice
console.log(user.name); // 输出:Get name => Alice

参数装饰器

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

function validateParam(target: any, methodName: string, paramIndex: number) {
  console.log(`Parameter ${paramIndex} of ${methodName} is decorated.`);
}

class Validator {
  greet(@validateParam name: string) {}
}
// 输出:Parameter 0 of greet is decorated.

装饰器工厂

装饰器工厂是一个返回装饰器函数的函数,允许传递参数定制装饰器行为。

js 实现装饰器

function log(message: string) {
  return function (target: any, key: string, descriptor: PropertyDescriptor) {
    console.log(`${message} - ${key} called.`);
    return descriptor;
  };
}

class Logger {
  @log('DEBUG')
  logMessage() {}
}

const logger = new Logger();
logger.logMessage(); // 输出:DEBUG - logMessage called.

注意事项

  • 装饰器在 JavaScript 中尚未成为正式标准,需依赖编译工具支持。
  • 装饰器执行顺序:参数装饰器 > 方法/属性装饰器 > 类装饰器(从内到外)。
  • 避免在装饰器中直接修改原型链,可能导致不可预期的行为。

通过上述方法,可以灵活使用装饰器增强代码的可读性和功能性。

标签: js
分享给朋友:

相关文章

js实现分页

js实现分页

实现分页的基本思路 分页功能通常需要处理数据分割、页码生成和用户交互。核心逻辑包括计算总页数、根据当前页截取数据、渲染页码按钮等。 前端分页实现(静态数据) 假设已有全部数据,仅需前端分页展示:…

js实现乘

js实现乘

JavaScript 实现乘法运算 在 JavaScript 中实现乘法运算可以通过多种方式完成,包括基本运算符、函数封装以及高级算法(如大数乘法)。以下是几种常见方法: 使用基本乘法运算符 Jav…

js实现目录

js实现目录

实现目录的基本思路 在JavaScript中实现目录功能通常涉及以下几个核心步骤:解析文档中的标题元素(如h1-h6),动态生成目录结构,并添加交互逻辑(如点击跳转)。以下是具体实现方法: 解析标题…

js实现vue路由

js实现vue路由

Vue 路由的基本实现 在 Vue.js 中实现路由功能通常使用 Vue Router 库。Vue Router 是 Vue.js 官方的路由管理器,用于构建单页面应用(SPA)。 安装 Vue R…

js实现文字滚动

js实现文字滚动

实现文字滚动的几种方法 使用CSS动画实现滚动 通过CSS的@keyframes和transform属性可以实现平滑的文字滚动效果。 <style> .scroll-text { w…

js验证码的实现

js验证码的实现

验证码的基本实现原理 验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。 纯前端验证码…