【NestJS入门到精通】装饰器
目录
- 方法装饰器
- 通过prototype添加属性、方法
- 属性装饰器
- 拓展
- 方法装饰器
- 参数装饰器
方法装饰器
ClassDecorator
定义了一个类装饰器 a,并将其应用于类 A。装饰器 a 会在类 A 被定义时执行。
const a:ClassDecorator = (target:any)=>{console.log(target,target)//[class A] [class A]
}@a
class A {constructor(){}
}
上面代码等价于下面代码
const a:ClassDecorator = (target:any)=>{console.log(target,target)//[class A] [class A]
}class A {constructor(){}
}
a(A)
通过prototype添加属性、方法
定义一个 ClassDecorator,这个装饰器的作用是修改类A 的原型,@a 装饰器为类 A 添加了一个 name 属性。具体来说,装饰器 a 将 name 属性添加到了 A 类的 prototype 上,因此所有通过 A 类创建的实例都能够访问这个 name 属性。
const a:ClassDecorator = (target:any)=>{target.prototype.name = "张三"
}@a
class A {constructor(){}
}const test:any = new A();
console.log(test)//A {}. 输出实例 A,内容包括 constructor 和原型链上的属性 `name`
console.log(test.name)//张三
-
动态添加属性:使用装饰器,你可以动态为类或其实例添加属性、方法或者进行其他操作,而不需要直接修改类的定义。这使得代码更加灵活,可以根据上下文条件来修改类的行为。
-
减少重复代码:如果你需要在多个类上应用相似的逻辑,比如为多个类都添加 name 属性,使用装饰器可以避免在每个类中都手动添加相同的代码。
-
提高可读性:通过装饰器,相关的逻辑集中在一个地方,便于理解和维护。你可以将通用功能提取到装饰器中,而不是散落在多个类中。
属性装饰器
PropertyDecorator
- target 是空对象 {},实际上是 A.prototype,这是因为 name 是实例属性,而实例属性存储在类的原型链中。
- key 是 name,表示被装饰的属性名称。
const a: PropertyDecorator = (target: any, key: string | symbol) => {console.log(target, key)//{} name
}class A {@apublic name: string;constructor() {this.name = "张三";}
}
-
灵活的元数据处理:你可以在属性被定义时拦截并处理它,添加额外的行为或逻辑。例如,记录属性的变化、定义特定的验证规则等。
-
解耦的功能增强:通过装饰器,你可以将逻辑与类的主要业务逻辑解耦开来。比如,可以为某个属性自动添加 getter/setter 方法,或者在装饰器中为属性附加元数据。
-
代码简洁性:装饰器可以让代码更加简洁和可读,减少在类中重复编写相同的逻辑。
拓展
const a: PropertyDecorator = (target: any, key: string | symbol) => {let value: string;Object.defineProperty(target, key, {get() {console.log( `修改后的值: ${value}`)// 修改返回的值return value},set(newvalue) {console.log(`${String(key)} 被赋值为 ${newvalue}`);value = newvalue;},});
};class A {@apublic name: string;constructor() {this.name = "张三"; // 当调用时,setter 会生效}
}const test = new A();
test.name = "里斯"
console.log(test.name);
打印的先后顺序
name 被赋值为 张三
name 被赋值为 里斯
修改后的值: 里斯
里斯
装饰器在类定义的时候就会被执行
方法装饰器
- target 是 A.prototype,即类 A 的原型对象,因为装饰器应用在类的实例方法 getName 上。
- key 是被装饰方法的名称,在这里是 “getName”
- descriptor 是方法的 属性描述符,包含关于方法的一些信息,例如可写性、可枚举性等。
const a: MethodDecorator = (target: any, key: string | symbol,descriptor:any) => {console.log(target,key,'descriptor')
};
class A {public name: string;constructor() {this.name = "张三"; }@agetName(){}
}
// console.log(target,key,'descriptor') 打印结果
{} getName {value: [Function: getName],writable: true,enumerable: false,configurable: true
}
参数装饰器
需要用到ParameterDecorator装饰器,且装饰器的第三个参数parameterIndex为参数的索引,即第几个参数。
- target:是方法所在类的原型对象。在这个例子中,target 为 {},这是 A.prototype,表示 A 类的原型。
- propertyKey:是方法的名称。在这个例子中是 “getName”,因为装饰器被应用在 getName 方法的参数上。
- parameterIndex:是参数的索引。在这个例子中是 1,表示装饰器应用在 getName 方法的第二个参数(age)上。
const a: ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => {console.log(target, propertyKey, parameterIndex); //{} getName 1
};class A {public name: string;constructor() {this.name = "张三";}getName(name: string, @a age: number) {// age 参数被装饰器修饰}
}
在写参数装饰器可能会报错,比如:

原因是因为设定的参数类型,与定义的ParameterDecorator类型不一致。
ParameterDecorator类型如下:
其中 propertyKey: string | symbol | undefined
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;
所以我们需要修改方法a的定义,上文已经是正确的定义方法。
const a: ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => {console.log(target, propertyKey, parameterIndex);
};
相关文章:
【NestJS入门到精通】装饰器
目录 方法装饰器通过prototype添加属性、方法 属性装饰器拓展 方法装饰器参数装饰器 方法装饰器 ClassDecorator 定义了一个类装饰器 a,并将其应用于类 A。装饰器 a 会在类 A 被定义时执行。 const a:ClassDecorator (target:any)>{console.log(target,targe…...
XML 编辑最简单好用的 QXmlEdit 软件已经完整中文化
XML 编辑最简单好用的 QXmlEdit 软件已经完整中文化 简介一、软件界面二、安装下载2.1 QXmlEdit 官方网站下载2.2 QXmlEdit 源代码下载2.3 QXmlEdit 软件中文版下载 三、QXmlEdit 编辑 ADCP 测量项目的 MMT 文件3.1 应用 XML 文件缩进3.2 使用 QXmlEdit 缩进编辑保存后…...
ref标签、style的scope
ref标签 作用:用于注册模板引用。 用在普通DOM标签上,获取的是DOM节点。用在组件标签上,获取的是组件实例对象。 DOM: <template><div class"person"><h2 ref"title2">上海</h2>&l…...
22年408数据结构
第一题: 解析: 观察一下这个程序:我们注意到最外层的循环是从i1开始的,每次ii*2,直到i<n为止,假设程序总共执行k次执行,则有2^(k1)>n。则k1>log(2)n这里是以2为底n的对数, k>log(2)…...
ubuntu 虚拟机将linux文件夹映射为windows网络位置
在使用虚拟机时可以选择将windows的文件夹设置为共享文件夹方便在虚拟机中访问windows中的文件,同理,也可以将linux的文件夹共享为一个网络文件夹,通过windows的添加一个网络位置功能,将linux的文件夹映射到windows本地,方便windows访问使用linux的文件夹 参照如下:https://blo…...
Pytho逻辑回归算法:面向对象的实现与案例详解
这里写目录标题 Python逻辑回归算法:面向对象的实现与案例详解引言一、逻辑回归算法简介1.1 损失函数1.2 梯度下降 二、面向对象的逻辑回归实现2.1 类的设计2.2 Python代码实现2.3 代码详解 三、逻辑回归案例分析3.1 案例一:简单二分类问题问题描述数据代…...
AWS WAF实战指南:从入门到精通
1. 引言 Amazon Web Services (AWS) Web Application Firewall (WAF) 是一款强大的网络安全工具,用于保护Web应用程序免受常见的Web漏洞攻击。本文将带您从入门到精通,深入探讨AWS WAF的实际应用策略,并提供具体案例,帮助您更好地保护您的Web应用程序。 2. AWS WAF基础 …...
k8s的部署
一、K8S简介 Kubernetes中文官网:Kubernetes GitHub:github.com/kubernetes/kubernetes Kubernetes简称为K8s,是用于自动部署、扩缩和管理容器化应用程序的开源系统,起源于Google 集群管理工具Borg。 Kubernetes集群组件逻辑图…...
C# 两个进程/exe通讯方式 两个应用程序通讯方式
C# 两个exe通讯方式 两个应用程序通讯方式 1. 命名管道(Named Pipes) 1.1. 概述 命名管道是一种用于在同一台机器或网络中不同进程之间进行双向通信的机制。它支持同步和异步通信,适用于需要高效数据传输的场景。 1.2. 特点 双向通信&am…...
ubuntu下打开摄像头
ubuntu下打开摄像头 在Ubuntu下,你可以使用cheese,这是一个开源的摄像头应用程序。如果你还没有安装它,可以通过以下命令安装: sudo apt-get updatesudo apt-get install cheese 安装完成后,你可以通过命令行启动它: cheese 或者,你也可以使用ffmpeg来打开摄像头并进…...
ABAP 表转JSON格式
FUNCTION ZRFC_FI_SEND_PAYPLAN2BPM. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *" VALUE(INPUT) TYPE ZSRFC_FI_SEND_PAYBPM_IN *" EXPORTING *" VAL…...
oceanbase的日志量太大,撑爆磁盘,修改下日志级别
oceanbase的日志量太大,撑爆磁盘,修改下日志级别: [adminlnpg ~]$ obclient -h127.0.0.1 -uroot -P2881 -plinux123 Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 3221561020 Server version: O…...
【C++11】lambda表达式
前言: 随着 C11 的发布,C 标准引入了许多新特性,使语言更加现代化,开发者编写的代码也变得更加简洁和易于维护。Lambda 表达式是其中一个重要的特性,它提供了一种方便的方式来定义匿名函数,这在函数式编程范…...
前端学习-css的背景(十六)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 背景颜色 语法格式 背景图片 语法格式 背景平铺 语法格式 背景图片位置 语法格式 参数代表的意思 参数是方位名词 参数是精确单位 参数是混合单位 背…...
使用Postman搞定各种接口token实战
现在许多项目都使用jwt来实现用户登录和数据权限,校验过用户的用户名和密码后,会向用户响应一段经过加密的token,在这段token中可能储存了数据权限等,在后期的访问中,需要携带这段token,后台解析这段token才…...
ssh连接慢的问题或远程连接服务超时
问题原因: 在SSH登录过程中,服务器会通过反向DNS查找客户端的主机名,然后与登录的IP地址进行匹配,以验证登录的合法性。如果客户端的IP没有域名或DNS服务器响应缓慢,这可能导致SSH登录过慢。为了解决这个问题…...
基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet模型【pytorch框架+python源码】
更多目标检测和图像分类识别项目可看我主页其他文章 功能演示: 基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet【pytorch框架,python,tkinter】_哔哩哔哩_bilibili (一)简介 基于卷积神…...
数据结构与算法:栈与队列的高级应用
目录 3.1 栈的高级用法 3.2 队列的深度应用 3.3 栈与队列的综合应用 总结 数据结构与算法:栈与队列的高级应用 栈和队列是两种重要的线性数据结构,它们在计算机科学和工程的许多领域都有广泛的应用。从函数调用到表达式求值,再到任务调度…...
macos php开发环境之macport安装的php扩展安装,php常用扩展安装,port中可用的所有php扩展列表
macos中,我们使用了port 安装了php后,默认只带有php基本的核心扩展的, 如果需要使用其他的扩展,如 redis, https, xdebug等扩展就需要我们手动来安装对应的扩展。 macos php开发环境 macport安装的php的方法见macos 中…...
使用Pytorch+Numpy+Matplotlib实现手写字体分类和图像显示
文章目录 1.引用2.内置图片数据集加载3.处理为batch类型4.设置运行设备5.查看数据6.绘图查看数据图片(1)不显示图片标签(2)打印图片标签(3)图片显示标签 7.定义卷积函数8.卷积实例化、损失函数、优化器9.训练和测试损失、正确率(1)训练(2)测试(3)循环(4)损失和正确率曲线(5)输出…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
