当前位置:首页 > JavaScript

js实现decorator

2026-02-01 03:15:36JavaScript

JavaScript 装饰器实现

装饰器是一种特殊类型的声明,可以附加到类、方法、访问器、属性或参数上。装饰器使用 @expression 形式,expression 必须求值为一个函数,该函数会在运行时被调用。

类装饰器

类装饰器应用于类的构造函数,可以用来观察、修改或替换类定义。

function logClass(target) {
  console.log('Class decorator applied to:', target.name);
  return target;
}

@logClass
class MyClass {
  constructor() {
    console.log('MyClass instance created');
  }
}

const instance = new MyClass();

方法装饰器

方法装饰器应用于方法的属性描述符,可以用来修改方法的行为。

function logMethod(target, propertyKey, descriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = function(...args) {
    console.log(`Calling method ${propertyKey} with args:`, args);
    const result = originalMethod.apply(this, args);
    console.log(`Method ${propertyKey} returned:`, result);
    return result;
  };

  return descriptor;
}

class Calculator {
  @logMethod
  add(a, b) {
    return a + b;
  }
}

const calc = new Calculator();
calc.add(2, 3);

属性装饰器

属性装饰器应用于类的属性,可以用来修改属性的行为。

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

class Person {
  @readonly
  name = 'John';
}

const person = new Person();
person.name = 'Jane'; // 会报错,因为属性是只读的

访问器装饰器

访问器装饰器应用于访问器的属性描述符,可以用来修改 getter 或 setter 的行为。

js实现decorator

function configurable(value) {
  return function(target, propertyKey, descriptor) {
    descriptor.configurable = value;
    return descriptor;
  };
}

class Circle {
  private _radius: number;

  constructor(radius: number) {
    this._radius = radius;
  }

  @configurable(false)
  get radius() {
    return this._radius;
  }
}

参数装饰器

参数装饰器应用于构造函数或方法的参数,可以用来添加元数据。

function validate(target, propertyKey, parameterIndex) {
  console.log(`Validating parameter ${parameterIndex} of ${propertyKey}`);
}

class Greeter {
  greet(@validate name: string) {
    console.log(`Hello, ${name}`);
  }
}

const greeter = new Greeter();
greeter.greet('World');

装饰器工厂

装饰器工厂是一个返回装饰器函数的函数,可以用来配置装饰器的行为。

function log(message: string) {
  return function(target, propertyKey, descriptor) {
    console.log(message);
    return descriptor;
  };
}

class Logger {
  @log('Logging method called')
  logMessage(message: string) {
    console.log(message);
  }
}

const logger = new Logger();
logger.logMessage('Hello, world!');

TypeScript 中的装饰器

在 TypeScript 中,需要启用 experimentalDecorators 编译器选项才能使用装饰器。

js实现decorator

{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

Babel 中的装饰器

使用 Babel 时,需要安装 @babel/plugin-proposal-decorators 插件来支持装饰器语法。

npm install --save-dev @babel/plugin-proposal-decorators

然后在 .babelrc 中配置插件:

{
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }]
  ]
}

注意事项

装饰器目前是 ECMAScript 的提案,尚未成为正式标准。在使用时需要注意兼容性问题。

装饰器的执行顺序是从上到下,从外到内。对于同一个目标,多个装饰器的应用顺序如下:

  1. 参数装饰器
  2. 方法/访问器/属性装饰器
  3. 类装饰器

标签: jsdecorator
分享给朋友:

相关文章

js实现复制

js实现复制

使用document.execCommand方法 在较旧的浏览器中,可以使用document.execCommand('copy')实现复制功能。创建一个临时的textarea或input元素,将需要…

js实现tab选项卡切换

js实现tab选项卡切换

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

jquery js

jquery js

jQuery 简介 jQuery 是一个快速、简洁的 JavaScript 库,简化了 HTML 文档遍历、事件处理、动画和 Ajax 交互。它兼容多种浏览器,提供易于使用的 API,使开发者能够更高…

js实现游标

js实现游标

使用JavaScript实现游标 在JavaScript中,可以通过操作DOM元素的cursor样式属性来实现自定义游标效果。以下是几种常见的实现方法: 修改默认鼠标指针样式 通过CSS的curso…

js实现投球

js实现投球

实现投球动画的基本思路 使用JavaScript和CSS动画结合的方式模拟投球效果。核心是通过改变元素的位置、旋转和缩放属性,配合定时器或CSS过渡实现平滑动画。 创建基础HTML结构 <di…

js实现密码

js实现密码

密码强度验证 使用正则表达式验证密码强度是一种常见方法。以下代码检查密码是否包含大小写字母、数字和特殊字符,且长度至少为8位: function checkPasswordStrength(pass…