TypeScript进阶(二)深入理解装饰器
✨ 专栏介绍
TypeScript是一种由微软开发的开源编程语言,它是JavaScript的超集,意味着任何有效的JavaScript代码都是有效的TypeScript代码。TypeScript通过添加静态类型和其他特性来增强JavaScript,使其更适合大型项目和团队开发。
在TypeScript专栏中,我们将深入探讨TypeScript的各个方面,包括语法、类型系统、模块化、面向对象编程等。我们将介绍如何使用TypeScript来构建可维护、可扩展和高效的应用程序。
TypeScript是一种开源的编程语言,它是JavaScript的超集,意味着所有的JavaScript代码都可以在TypeScript中运行。TypeScript添加了静态类型检查和其他一些新特性,以提高代码的可读性、可维护性和可扩展性。
文章目录
- ✨ 专栏介绍
- 引言
- 基本概念
- 装饰器的分类
- 1. 类装饰器
- 2. 方法装饰器
- 3. 属性装饰器
- 4. 参数装饰器
- 装饰器工厂
- 装饰器的执行顺序
- 装饰器的应用场景
- 日志记录
- 权限控制
- 表单验证
- 性能分析
- 总结
- 😶 写在结尾
引言
TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集,为 JavaScript 添加了静态类型检查和其他一些特性。装饰器是 TypeScript 中一个非常强大的特性,它可以用来修改类、方法、属性等的行为。本文将深入探讨 TypeScript 装饰器的原理和用法。
基本概念
装饰器是一种特殊类型的声明,它可以被附加到类声明、方法、属性或参数上,以修改类的行为。装饰器使用 @
符号作为前缀,并放置在被修饰项之前。
装饰器的分类
在 TypeScript 中,装饰器可以分为四种类型:类装饰器、方法装饰器、属性装饰器和参数装饰器。
1. 类装饰器
类装饰器是应用于类构造函数的函数。它接收一个参数,即被修饰的类构造函数,并可以在不修改原始类定义的情况下扩展或修改该类。
function logClass(target: any) {console.log(target);
}@logClass
class MyClass {// ...
}
2. 方法装饰器
方法装饰器是应用于方法定义的函数。它接收三个参数:被修饰的类的原型、方法的名称和方法的属性描述符。方法装饰器可以用来修改方法的行为,例如添加日志、验证等。
function logMethod(target: any, methodName: string, descriptor: PropertyDescriptor) {console.log(target, methodName, descriptor);
}class MyClass {@logMethodmyMethod() {// ...}
}
3. 属性装饰器
属性装饰器是应用于属性声明的函数。它接收两个参数:被修饰的类的原型和属性名称。属性装饰器可以用来修改属性的行为,例如添加验证、计算等。
function logProperty(target: any, propertyName: string) {console.log(target, propertyName);
}class MyClass {@logPropertymyProperty: string;
}
4. 参数装饰器
参数装饰器是应用于函数参数声明的函数。它接收三个参数:被修饰的类的原型、方法名称和参数索引。参数装饰器可以用来修改函数参数的行为,例如添加验证、转换等。
function logParameter(target: any, methodName: string, parameterIndex: number) {console.log(target, methodName, parameterIndex);
}class MyClass {myMethod(@logParameter param1: string) {// ...}
}
装饰器工厂
除了直接使用装饰器函数,我们还可以使用装饰器工厂来创建装饰器。装饰器工厂是一个返回装饰器函数的函数,它可以接收参数,并根据参数返回不同的装饰器。
function logClassFactory(prefix: string) {return function (target: any) {console.log(`${prefix} ${target}`);};
}@logClassFactory('Logging')
class MyClass {// ...
}
装饰器的执行顺序
当一个类有多个装饰器时,它们的执行顺序是从下到上、从右到左的。这意味着最后一个装饰器先执行,然后依次向上执行。
function log1(target: any) {console.log('log1');
}function log2(target: any) {console.log('log2');
}@log1
@log2
class MyClass {// ...
}
输出结果:
log2 log1
装饰器的应用场景
装饰器在 TypeScript 中有广泛的应用场景,例如:
- 日志记录:可以使用类装饰器或方法装饰器来添加日志记录功能。
- 权限控制:可以使用方法装饰器来限制只有特定角色或权限才能调用某个方法。
- 表单验证:可以使用属性装饰器或参数装饰器来验证表单字段的合法性。
- 性能分析:可以使用方法装饰器来记录方法的执行时间,以便进行性能分析。
日志记录
当涉及到日志记录时,可以使用类装饰器或方法装饰器来添加日志记录功能。例如,我们可以创建一个类装饰器 @logClass
,在类的构造函数中添加日志记录的逻辑。这样,在每次创建该类的实例时,都会自动记录相关日志信息。
function logClass(target: any) {const originalConstructor = target;const newConstructor: any = function (...args: any[]) {console.log(`Creating instance of ${originalConstructor.name}`);return new originalConstructor(...args);};newConstructor.prototype = originalConstructor.prototype;return newConstructor;
}@logClass
class MyClass {constructor() {console.log('MyClass constructor');}
}const myInstance = new MyClass();
权限控制
在权限控制方面,可以使用方法装饰器来限制只有特定角色或权限才能调用某个方法。例如,我们可以创建一个方法装饰器 @checkPermission
,在调用被修饰的方法之前进行权限验证。
function checkPermission(target: any, methodName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {// 检查用户权限if (hasPermission()) {return originalMethod.apply(this, args);} else {throw new Error('You do not have permission to access this method.');}};
}class MyClass {@checkPermissionmyMethod() {console.log('Executing myMethod');}
}const myInstance = new MyClass();
myInstance.myMethod(); // 只有具有权限的用户才能成功调用该方法
表单验证
在表单验证方面,可以使用属性装饰器或参数装饰器来验证表单字段的合法性。例如,我们可以创建一个属性装饰器 @validateField
,在设置属性值时进行验证。
function validateField(target: any, propertyName: string) {const originalValue = target[propertyName];Object.defineProperty(target, propertyName, {get() {return originalValue;},set(value: any) {// 进行字段验证if (isValid(value)) {originalValue = value;} else {throw new Error(`Invalid value for ${propertyName}`);}},});
}class Form {@validateFieldname: string;constructor(name: string) {this.name = name;}
}const form = new Form('John');
form.name = 'Jane'; // 合法的值
form.name = ''; // 非法的值,会抛出错误
性能分析
在性能分析方面,可以使用方法装饰器来记录方法的执行时间,以便进行性能分析。例如,我们可以创建一个方法装饰器 @measurePerformance
,在调用被修饰的方法时记录执行时间。
function measurePerformance(target: any, methodName: string, descriptor: PropertyDescriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args: any[]) {const start = performance.now();const result = originalMethod.apply(this, args);const end = performance.now();console.log(`Method ${methodName} took ${end - start} milliseconds to execute.`);return result;};
}class MyClass {@measurePerformancemyMethod() {// 执行一些耗时的操作for (let i = 0; i < 1000000000; i++) {// ...}}
}const myInstance = new MyClass();
myInstance.myMethod(); // 输出方法执行时间
这些示例展示了装饰器在不同场景下的应用。通过使用装饰器,我们可以轻松地为类、方法、属性或参数添加额外的功能和行为,从而实现更加灵活和可扩展的代码结构。
总结
本文深入探讨了 TypeScript 装饰器的原理和用法。装饰器是 TypeScript 中一个非常强大的特性,它可以用来修改类、方法、属性等的行为。通过使用装饰器,我们可以轻松地扩展和修改现有的类和方法,使其具有更多的功能和特性。
😶 写在结尾
前端设计模式专栏
设计模式是软件开发中不可或缺的一部分,它们帮助我们解决了许多常见问题,并提供了一种优雅而可靠的方式来构建应用程序。在本专栏中,我们介绍了所有的前端设计模式,包括观察者模式、单例模式、策略模式等等。通过学习这些设计模式,并将其应用于实际项目中,我们可以提高代码的可维护性、可扩展性和可重用性。希望这个专栏能够帮助你在前端开发中更好地应用设计模式,写出高质量的代码。点击订阅前端设计模式专栏
Vue专栏
Vue.js是一款流行的JavaScript框架,用于构建用户界面。它采用了MVVM(Model-View-ViewModel)的架构模式,通过数据驱动和组件化的方式,使开发者能够更轻松地构建交互性强、可复用的Web应用程序。在这个专栏中,我们将深入探讨Vue.js的核心概念、组件开发、状态管理、路由和性能优化等方面的知识。我们将学习如何使用Vue.js构建响应式的用户界面,并探索其强大的生态系统,如Vue Router和Vuex、Pinia。通过学习这些内容,你将能够成为一名熟练的Vue.js开发者,并能够应用这些知识来构建复杂而高效的Web应用程序。点击订阅Vue专栏
JavaScript(ES6)专栏
JavaScript是一种广泛应用于网页开发和后端开发的脚本语言。它具有动态性、灵活性和易学性的特点,是构建现代Web应用程序的重要工具之一。在这个专栏中,我们将深入探讨JavaScript语言的基本语法、DOM操作、事件处理、异步编程以及常见算法和数据结构等内容。此外,我们还将介绍ES6(ECMAScript 2015)及其后续版本中引入的新特性,如箭头函数、模块化、解构赋值等。通过学习这些内容,你将能够成为一名熟练的JavaScript开发者,并能够应用这些知识来构建出高质量和可维护的Web应用程序。点击订阅JavaScript(ES6)专栏
相关文章:

TypeScript进阶(二)深入理解装饰器
✨ 专栏介绍 TypeScript是一种由微软开发的开源编程语言,它是JavaScript的超集,意味着任何有效的JavaScript代码都是有效的TypeScript代码。TypeScript通过添加静态类型和其他特性来增强JavaScript,使其更适合大型项目和团队开发。 在TypeS…...

书生·浦语第三次作业
我最近在参加书生浦语大模型实战营,这是第三次作业打卡! 如果你也想两周玩转大模型微调,部署与测评全链路。报名链接:invite 书生浦语大模型实战营报名 邀请码可以填026014 一、基础作业:复现课程知识库助手搭建过程…...
GPT实战系列-LangChain + ChatGLM3构建天气查询助手
GPT实战系列-LangChain ChatGLM3构建天气查询助手 用ChatGLM的工具可以实现很多查询接口和执行命令,而LangChain是很热的大模型应用框架。如何联合它们实现大模型查询助手功能?例如调用工具实现网络天气查询助手功能。 LLM大模型相关文章: …...
LeetCode 2696.删除子串后的字符串最小长度:栈
【LetMeFly】2696.删除子串后的字符串最小长度:栈 力扣题目链接:https://leetcode.cn/problems/minimum-string-length-after-removing-substrings/ 给你一个仅由 大写 英文字符组成的字符串 s 。 你可以对此字符串执行一些操作,在每一步操…...

Xcode15 升级问题记录
这里写自定义目录标题 新版本Xcode15升级问题1:rsync error: some files could not be transferred (code 23) at ...参考 新版本Xcode15升级 下载地址:https://developer.apple.com/download/all/ 我目前使用的版本是Xcode15.2 我新创建了一个项目&…...
List、Set、Map有什么区别?
List、Set和Map是Java中的三种基本数据结构,它们在元素重复性、有序性和用途方面存在显著的区别。 元素重复性: List允许有重复的元素。任何数量的重复元素都可以在不影响现有重复元素的值及其索引的情况下插入到List集合中。 Set集合不允许元素重复。…...

centOS系统yum安装和卸载mongodb
0.1 什么是mongodb? 0.2 Mongodb是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 0.3 Mongodb是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据…...

2023年12月 C/C++(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:数的输入和输出 输入一个整数和双精度浮点数,先将浮点数保留2位小数输出,然后输出整数。 时间限制:1000 内存限制:65536 输入 一行两个数,分别为整数N(不超过整型范围),双精度浮点数F,以一个空格分开。 输出 一行两个数,分…...

Python爬虫---Scrapy项目的创建及运行
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖 掘,信息处理或存储历史数据等一系列的程序中。 1. 安装scrapy: pip install scrapy 注意:需要安装在python解释器相同的位置,例如…...
PyTorch: torch.nn 子模块及其在循环神经网络中的应用
目录 torch.nn子模块详解 nn.utils.rnn.PackedSequence 参数说明 注意事项 示例代码 nn.utils.rnn.pack_padded_sequence 参数说明 返回值 注意事项 示例代码 nn.utils.rnn.pad_packed_sequence 参数说明 返回值 注意事项 示例代码 nn.utils.rnn.pad_sequence …...

【QT】自定义代理类
目录 1 我们为什么要使用自定义代理类? 2 自定义代理类的基本设计要求 3 自定义代理的功能 4 基于QSpinBox的自定义代理类 5 自定义代理类的使用 1 我们为什么要使用自定义代理类? 传统的模型-视图框架可以让我们实现逻辑展示相分离,我们…...
线程休眠、线程让步、线程优先级相关内容学习笔记
1、线程休眠 (1)sleep() 如果需要让当前正在执行的线程暂停一段时间,并进入阻塞状态(Timed_Waiting),则可以通过调用Thread类的静态sleep()方法来实现。 static void sleep(long millis):让当前正在执行的线…...
paddle指定运行gpu
在PaddlePaddle中指定使用GPU进行运行非常简单。首先,确保你的机器上已经安装了CUDA和cuDNN,并且正确配置了GPU环境。然后,按照以下步骤进行操作: 导入PaddlePaddle库: import paddle设置使用的设备为GPU:…...

Java异常及网络编程
异常续 throws关键字 当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。 package exception; /*** 测试异常的抛出*/ public clas…...

通过 Elastic Stack 充分利用电信领域生成式 AI 的力量
作者:Elastic Piotr Kobziakowski, Jrgen Obermann 在瞬息万变的电信领域,Elastic Stack 与生成式 AI 的集成正在开创运营效率和创新的新时代。 这些技术不仅增强了网络运营,而且还彻底改变了各个部门的内部流程。 下面,我们将深入…...

Redis:原理速成+项目实战——Redis实战8(基于Redis的分布式锁及优化)
👨🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习 🌌上期文章:Redis:原理速成项目实战——Redis实战7(优惠券秒杀细节解决超卖、一人一单问题) Ὅ…...

江山易改本性难移之ZYNQ SDK QSPI固化bug及其解决方法
之前在Vivado2018.3通过QSPI方式固化程序时出现问题,显示flash擦除成功,但最后总是不能写入到flash中。 查资料发现从VIVADO 2017.3版本开始,Xilinx官方为了使Zynq-7000和Zynq UltraScale 实现流程相同,在QSPI FLASH使用上做了变化…...
系列三十六、注解版Spring、SpringMVC配置文件
一、注解版Spring、SpringMVC配置文件 1.1、pom <dependencies><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.5.RELEASE</version><…...

爬虫你需要知道的:什么是http请求
1. 什么是http请求 我们将通过发送http请求来获取网页内容。http是HyperText Transfer Protocol的缩写,意思是超文本传输协议,它是一种客户端和服务器之间的请求响应协议。 浏览器就可以看作是一个客户端,当我们在浏览器地址栏输入想访问的…...

MCU FT61F14x入门
目录 前言一、CMIDE的使用二、系统时钟与睡眠2.1 上电复位 (POR)与系统复位2.2 振荡器和系统时钟2.3 SLEEP睡眠模式 (POWER-DOWN)2.4 低电压检测/比较器 (LVD) 三、I/O端口与中断四、串口USART五、定时器六、ADC七、EEPROM 前言 FT61F14x是辉芒微电子的微控制器,是一…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

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

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...