当前位置: 首页 > news >正文

【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 属性。具体来说,装饰器 aname 属性添加到了 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 缩进编辑保存后&#xf…...

ref标签、style的scope

ref标签 作用&#xff1a;用于注册模板引用。 用在普通DOM标签上&#xff0c;获取的是DOM节点。用在组件标签上&#xff0c;获取的是组件实例对象。 DOM&#xff1a; <template><div class"person"><h2 ref"title2">上海</h2>&l…...

22年408数据结构

第一题&#xff1a; 解析&#xff1a; 观察一下这个程序&#xff1a;我们注意到最外层的循环是从i1开始的&#xff0c;每次ii*2&#xff0c;直到i<n为止&#xff0c;假设程序总共执行k次执行&#xff0c;则有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逻辑回归算法&#xff1a;面向对象的实现与案例详解引言一、逻辑回归算法简介1.1 损失函数1.2 梯度下降 二、面向对象的逻辑回归实现2.1 类的设计2.2 Python代码实现2.3 代码详解 三、逻辑回归案例分析3.1 案例一&#xff1a;简单二分类问题问题描述数据代…...

AWS WAF实战指南:从入门到精通

1. 引言 Amazon Web Services (AWS) Web Application Firewall (WAF) 是一款强大的网络安全工具,用于保护Web应用程序免受常见的Web漏洞攻击。本文将带您从入门到精通,深入探讨AWS WAF的实际应用策略,并提供具体案例,帮助您更好地保护您的Web应用程序。 2. AWS WAF基础 …...

k8s的部署

一、K8S简介 Kubernetes中文官网&#xff1a;Kubernetes GitHub&#xff1a;github.com/kubernetes/kubernetes Kubernetes简称为K8s&#xff0c;是用于自动部署、扩缩和管理容器化应用程序的开源系统&#xff0c;起源于Google 集群管理工具Borg。 Kubernetes集群组件逻辑图…...

C# 两个进程/exe通讯方式 两个应用程序通讯方式

C# 两个exe通讯方式 两个应用程序通讯方式 1. 命名管道&#xff08;Named Pipes&#xff09; 1.1. 概述 命名管道是一种用于在同一台机器或网络中不同进程之间进行双向通信的机制。它支持同步和异步通信&#xff0c;适用于需要高效数据传输的场景。 1.2. 特点 双向通信&am…...

ubuntu下打开摄像头

ubuntu下打开摄像头 在Ubuntu下,你可以使用cheese,这是一个开源的摄像头应用程序。如果你还没有安装它,可以通过以下命令安装: sudo apt-get updatesudo apt-get install cheese 安装完成后,你可以通过命令行启动它: cheese 或者,你也可以使用ffmpeg来打开摄像头并进…...

ABAP 表转JSON格式

FUNCTION ZRFC_FI_SEND_PAYPLAN2BPM. *"---------------------------------------------------------------------- *"*"本地接口&#xff1a; *" IMPORTING *" VALUE(INPUT) TYPE ZSRFC_FI_SEND_PAYBPM_IN *" EXPORTING *" VAL…...

oceanbase的日志量太大,撑爆磁盘,修改下日志级别

oceanbase的日志量太大&#xff0c;撑爆磁盘&#xff0c;修改下日志级别&#xff1a; [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表达式

前言&#xff1a; 随着 C11 的发布&#xff0c;C 标准引入了许多新特性&#xff0c;使语言更加现代化&#xff0c;开发者编写的代码也变得更加简洁和易于维护。Lambda 表达式是其中一个重要的特性&#xff0c;它提供了一种方便的方式来定义匿名函数&#xff0c;这在函数式编程范…...

前端学习-css的背景(十六)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 背景颜色 语法格式 背景图片 语法格式 背景平铺 语法格式 背景图片位置 语法格式 参数代表的意思 参数是方位名词 参数是精确单位 参数是混合单位 背…...

使用Postman搞定各种接口token实战

现在许多项目都使用jwt来实现用户登录和数据权限&#xff0c;校验过用户的用户名和密码后&#xff0c;会向用户响应一段经过加密的token&#xff0c;在这段token中可能储存了数据权限等&#xff0c;在后期的访问中&#xff0c;需要携带这段token&#xff0c;后台解析这段token才…...

ssh连接慢的问题或远程连接服务超时

问题原因&#xff1a; 在SSH登录过程中&#xff0c;服务器会通过反向DNS查找客户端的主机名&#xff0c;然后与登录的IP地址进行匹配&#xff0c;以验证登录的合法性。如果客户端的IP没有域名或DNS服务器响应缓慢&#xff0c;这可能导致SSH登录过慢。为了解决这个问题&#xf…...

基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet模型【pytorch框架+python源码】

更多目标检测和图像分类识别项目可看我主页其他文章 功能演示&#xff1a; 基于卷积神经网络的蔬菜识别系统&#xff0c;resnet50&#xff0c;mobilenet【pytorch框架&#xff0c;python&#xff0c;tkinter】_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神…...

数据结构与算法:栈与队列的高级应用

目录 3.1 栈的高级用法 3.2 队列的深度应用 3.3 栈与队列的综合应用 总结 数据结构与算法&#xff1a;栈与队列的高级应用 栈和队列是两种重要的线性数据结构&#xff0c;它们在计算机科学和工程的许多领域都有广泛的应用。从函数调用到表达式求值&#xff0c;再到任务调度…...

macos php开发环境之macport安装的php扩展安装,php常用扩展安装,port中可用的所有php扩展列表

macos中&#xff0c;我们使用了port 安装了php后&#xff0c;默认只带有php基本的核心扩展的&#xff0c; 如果需要使用其他的扩展&#xff0c;如 redis, https&#xff0c; 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)输出…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

CppCon 2015 学习:REFLECTION TECHNIQUES IN C++

关于 Reflection&#xff08;反射&#xff09; 这个概念&#xff0c;总结一下&#xff1a; Reflection&#xff08;反射&#xff09;是什么&#xff1f; 反射是对类型的自我检查能力&#xff08;Introspection&#xff09; 可以查看类的成员变量、成员函数等信息。反射允许枚…...

41道Django高频题整理(附答案背诵版)

解释一下 Django 和 Tornado 的关系&#xff1f; Django和Tornado都是Python的web框架&#xff0c;但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架&#xff0c;鼓励快速开发和干净、实用的设计。它遵循MVC设计&#xff0c;并强调代码复用。Django有…...