当前位置:首页 > JavaScript

js实现decorator

2026-03-14 01:28:20JavaScript

装饰器(Decorator)基础概念

装饰器是一种特殊类型的声明,能够附加到类、方法、访问器、属性或参数上。装饰器通过@expression形式使用,其中expression求值后必须是一个函数。

启用装饰器语法

在JavaScript中,装饰器目前处于提案阶段(Stage 3),需要通过Babel或TypeScript进行转译才能使用:

  • Babel需要@babel/plugin-proposal-decorators插件
  • TypeScript需在tsconfig.json中启用experimentalDecorators
// tsconfig.json示例
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}

类装饰器实现

类装饰器接收构造函数作为参数,可以修改或替换类定义:

function sealed(constructor) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class MyClass {}

方法装饰器实现

方法装饰器接收三个参数:目标对象、属性名和属性描述符:

js实现decorator

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

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

属性装饰器实现

属性装饰器接收目标对象和属性名,可用于修改属性描述符:

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

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

访问器装饰器

访问器装饰器与方法装饰器类似,应用于getter/setter:

js实现decorator

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

class Person {
  @configurable(false)
  get name() {
    return 'default';
  }
}

参数装饰器

参数装饰器应用于构造函数或方法参数:

function validate(target, key, index) {
  // 添加参数验证逻辑
}

class ApiService {
  fetch(@validate id) {
    // ...
  }
}

装饰器工厂模式

通过工厂函数创建可配置的装饰器:

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

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

第三方装饰器库

常用装饰器工具库:

  • core-decorators:提供@deprecated@debounce等实用装饰器
  • lodash-decorators:提供Lodash函数对应的装饰器版本
import { deprecated } from 'core-decorators';

class MyClass {
  @deprecated('Use newMethod instead')
  oldMethod() {}
}

注意事项

  1. 装饰器执行顺序:参数装饰器 → 方法/访问器/属性装饰器 → 类装饰器
  2. 装饰器不能用于函数声明(仅适用于类和方法)
  3. TypeScript实现与Babel实现存在细微差异
  4. 装饰器中的this绑定需要注意上下文

标签: jsdecorator
分享给朋友:

相关文章

js实现点击显示和隐藏

js实现点击显示和隐藏

实现点击显示和隐藏的JavaScript方法 使用classList.toggle切换类名 通过添加/移除CSS类控制元素的显示与隐藏,需提前在CSS中定义隐藏样式(如display: none)。…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(s…

js树实现

js树实现

树的基本概念 树是一种非线性的数据结构,由节点和边组成。每个节点包含一个值和指向子节点的引用。树的顶部节点称为根节点,没有子节点的节点称为叶节点。 树的实现方式 在JavaScript中,树可以通过…

js实现密码

js实现密码

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

js节流实现

js节流实现

节流的概念 节流(Throttle)是一种限制函数执行频率的技术,确保函数在一定时间间隔内只执行一次。常用于滚动事件、窗口调整等高频触发的场景。 基础实现方法 使用时间戳判断是否执行函数:…

js怎么实现异步

js怎么实现异步

异步实现方法 JavaScript中实现异步操作主要通过以下几种方式: Promise Promise是ES6引入的异步解决方案,用于处理异步操作的成功或失败状态。 const promise =…