当前位置:首页 > 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实现图片预览

使用FileReader API实现图片预览 通过FileReader对象读取用户选择的图片文件并显示预览: const input = document.getElementById('image…

js轮播图实现原理

js轮播图实现原理

轮播图的基本原理 轮播图通过动态切换显示的内容(图片、文本等)实现视觉上的滑动效果。核心原理是利用CSS和JavaScript控制元素的显示与隐藏,或通过变换位置实现滑动动画。 实现方法一:…

js实现论坛

js实现论坛

实现论坛的基本功能 使用JavaScript实现一个论坛需要结合前端和后端技术。前端可以使用React、Vue或Angular等框架,后端可以选择Node.js配合Express或Koa框架。数据库可…

js实现变形

js实现变形

使用 CSS 和 JavaScript 实现元素变形 在 JavaScript 中实现变形效果通常结合 CSS 的 transform 属性,通过动态修改该属性实现元素的旋转、缩放、倾斜或平移。 基…

js 实现滚动

js 实现滚动

实现滚动的方法 使用 window.scrollTo() window.scrollTo() 方法可以滚动到文档中的特定位置。可以指定 x 和 y 坐标,或者使用平滑滚动的选项。 // 滚动到指定位…

js实现的游戏

js实现的游戏

JavaScript 游戏开发基础 JavaScript 是开发网页游戏的流行选择,因其无需插件即可在浏览器中运行。以下是一些关键技术和资源: HTML5 Canvas Canvas 提供了绘制图形…