JS装饰器如何在项目中使用

JS 装饰器概述

JavaScript 装饰器是一种以 @ 符号开头的特殊语法,放在目标代码的前面用于包装或扩展代码功能。

JavaScript 的装饰器语法目前仍处于提案阶段,现阶段使用的话需要通过 babel 等方式进行编译之后,才能在浏览器正常运行。

装饰器分为两种:类装饰器,类成员装饰器,分别用于装饰 类以及类的成员。

语法

装饰器语法分为两部分。

首先是装饰器的定义,装饰器定义是编写一个函数,函数会接受所装饰的内容作为参数。

类装饰器和类型成员装饰器只是在接收的参数上不同。

而装饰器的使用则是使用 @ 符号加上定义的装饰器名称(即装饰器的函数名)

kotlin 复制代码
// 定义一个类装饰器
const classDecorator = (target) => {
	// do something
}

// 使用装饰器
@classDecorator
class Human {
}

类装饰器

类装饰器接收一个参数,即类的本身。

typescript 复制代码
const classDecorator = (target) => {
	console.log(`species is ${target.species}`); // species is human
}

// 使用装饰器
@classDecorator
class Human {
	static species = 'human';
}

类成员装饰器

类成员可以是类的属性,方法,或者是 getter 或 setter 等;类成员装饰器函数接收三个参数,分别是类本身,成员名称,成员修饰符(就是表示属性的是否可枚举,可读,可配置等的对象)

ini 复制代码
const speciesDecorator = (target, name, descriptor) => {
  console.log({ target, name, descriptor });
}

class Human {
  @speciesDecorator
  static species = 'Human';
}

装饰器输出结果为:

比如我们可以利用 descriptor 这个参数来做限制属性为不可枚举

typescript 复制代码
const speciesDecorator = (target, name, descriptor) => {
  console.log({ target, name, descriptor });
  descriptor.enumerable = false; // 将属性变为不可枚举
}

class _Human {
  static species = 'Human';
}
console.log(Object.keys(_Human)); // ['species']

class Human {
  @speciesDecorator
  static species = 'Human';
}
console.log(Object.keys(Human)); // []

同时使用多个装饰器

装饰器是可以叠加使用的,使用多个装饰器只需要在代码前面添加多个装饰器的使用即可

ini 复制代码
const noEnumerable = (target, name, descriptor) => {
  // 将属性改为不可枚举
  descriptor.enumerable = false;
}

const readonly = (target, name, descriptor) => {
  // 将属性改为只读
  descriptor.writable = false;
}


class Human {
  @noEnumerable
  @readonly
  static species = 'human';
}

console.log(Object.keys(Human)); // []
console.log(Human.species); // human
Human.species = 'new human';
console.log(Human.species); // human

装饰器的执行顺序

  • 装饰器在类定义时即执行

  • 先执行类成员装饰器,类成员装饰器执行完后,再执行类装饰器

  • 类成员装饰器的先后执行取决于成员的定义顺序

typescript 复制代码
const classDecorator = (target) => {
  console.log('类装饰器执行')
}

const speciesDecorator_1 = (target, name, descriptor) => {
  console.log('species_1 装饰器执行')
}

const speciesDecorator_2 = (target, name, descriptor) => {
  console.log('species_2 装饰器执行')
}

// 使用装饰器
@classDecorator
class Human {
  @speciesDecorator_1
	static species_1 = 'human';
  @speciesDecorator_2
	static species_2 = 'human';
}

执行结果为:

species_1 装饰器执行

species_2 装饰器执行

类装饰器执行

如何在vite项目中使用decorator

  • 安装两个包
css 复制代码
 p i @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
  • vite配置
php 复制代码
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [
    react({
      babel: {
        plugins: [
          ["@babel/plugin-proposal-decorators", { legacy: true }],
          ["@babel/plugin-proposal-class-properties", { loose: true }],
        ],
      },
    }),
  ],
});
相关推荐
LaughingZhu2 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫2 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux2 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水3 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger4 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)4 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态4 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态4 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart4 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter
放下华子我只抽RuiKe54 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架