当前位置:首页 > 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.

装饰器工厂

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

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实现轮播图

基础轮播图实现 使用HTML、CSS和JavaScript实现一个简单的自动轮播图。HTML结构包含一个容器和多个图片项。 <div class="slider"> <div…

js实现图片轮播

js实现图片轮播

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

js 实现继承

js 实现继承

原型链继承 通过让子类的原型对象指向父类的实例来实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Par…

js 实现分页

js 实现分页

实现分页的基本逻辑 分页功能通常需要后端返回数据总量或总页数,前端根据当前页码和每页条数截取对应数据。以下是一个基于JavaScript的简单分页实现方案: 前端分页实现 假设已有从后端获取的完整数…

js实现延迟

js实现延迟

实现延迟的方法 在JavaScript中,实现延迟操作有多种方式,以下是几种常见的方法: 使用setTimeout函数 setTimeout是JavaScript中最常用的延迟执行方法。它接受一个回…

js实现vr

js实现vr

使用WebXR API实现VR体验 WebXR是浏览器中实现VR和AR体验的标准API,它取代了早期的WebVR。现代浏览器如Chrome、Edge和Firefox已支持WebXR。 // 初始化W…