一文说明,TypeScript 的装饰器_typescript logo
liuian 2025-09-04 11:56 4 浏览
●装饰器 ( Decorators )
●注意 : 装饰器目前是一项实验性特性,在未来的版本中可能会发生改变
●装饰器一般使用在以下几个地方
○类
○类属性
○类方法
○类方法的参数
○通过这些我们也能看得出来, 其实说白了, 就是在类中会使用到装饰器
●装饰器的意义 :
○说白了, 装饰器就是一个方法, 可以注入到 类, 属性, 方法 中对其进行一些扩展
○让我们的一个类变得更加的多样化, 更加的完善
类装饰器
●其实就是自己书写一个方法, 对一个类进行扩展
// 准备一个装饰器函数
function fn(params: any) {
// params 就是将来 fn 去装饰的类
params.prototype.name = 'Jack'
params.prototype.sayHi = function () { console.log('hello world') }
}
●我们就可以在定义这个类的时候, 使用 fn 方法对其进行装饰
@fn
class Person {
constructor () {}
}
// 使用 Person 类去创建实例
// 在创建的时候, 会先执行一遍 fn 装饰器函数
const user = new Person()
console.log(user.name) // 'Jack'
user.sayHi() // 'hello world'
●看似好像没有什么用处
○其实装饰器主要的作用就是在类的原型上去扩展一些方法
○来看一个例子吧
原始形态
class Person {
constructor () {}
play () {}
study () {}
sleep () {}
}
class Student {
constructor () {}
play () {}
study () {}
sleep () {}
}
class Teacher {
constructor () {}
play () {}
study () {}
sleep () {}
}
●我们发现每一个类里面都会有一个 play 一个 study 一个 sleep 方法
●这个时候, 我们就是在重复的书写代码
●我们这个时候就想到一个内容, 叫做继承
继承实现
class People {
constructor () {}
play () {}
study () {}
sleep () {}
}
// 每次定义其他类的时候进行继承
class Student extends People {}
class Person extends People {}
class Teacher extends People {}
●我们发现效果是可以实现的
装饰器实现
function fn(params: any) {
params.prototype.play = function () {}
params.prototype.study = function () {}
params.prototype.sleep = function () {}
}
@fn
class Student {}
@fn
class Person {}
@fn
class Teacher {}
●同样的内容, 我们用装饰器也可以实现, 我们发现和继承没有什么区别
●但是, 我们如果用装饰器实现的话, 可以通过装饰器, 把不同的内容分开, 实现更加灵活
function addPlay(params: any) {
params.prototype.play = function () {}
}
function addStudy(params: any) {
params.prototype.study = function () {}
}
function addSleep(params: any) {
params.prototype.sleep = function () {}
}
// 扩展 study 和 sleep
@addStudy
@addSleep
class Student {}
// 扩展 play 和 sleep
@addPlay
@addSleep
class Person {}
// 扩展 play 和 study
@addPlay
@addStudy
class Teacher {}
●这样看起来是不是灵活了很多呢
类属性装饰器
●顾名思义, 就是用来对于类里面属性的扩展
●注意 : 可以修改属性的值, 但是不能修改该属性的类型限制
// fn 函数用来生成装饰器函数
// 目的: 为了将来使用装饰器的时候可以传递参数
function formatTime(time: Date) {
// 把这个返回值函数当做装饰器函数
return function (params: any, key: string) {
// params 就是将来 fn 去装饰的类
// key 就是你想修改的属性
// 做一个简单的格式化时间的逻辑
let timeStr = `${ time.getFullYear() }-${ time.getMonth() + 1 }-${ time.getDate() }`
Object.defineProperty(params, key, {
value: timeStr
})
}
}
// 创建一个类
class Student {
// 在创建属性的时候直接对该属性进行赋值
@formatTime(new Date(1652500063190))
time: string
constructor () {}
}
const s1 = new Student()
console.log(s1.time) // '2022-5-14'
●这样我们在定义类的时候, 可以根据装饰器对于某些属性进行修饰
类方法的装饰器
●同样的, 我们的方法装饰器就是用来对方法进行一些修饰
// 利用 fn 做一个装饰器工厂
// 目的: 还是要在使用装饰器的时候可以接受参数
function fn(x: string, y: number) {
// 返回一个真实的装饰器函数
return function (params: any, name: string, descriptor:TypedPropertyDescriptor<Function>) {
// params 接受的就是当前类的实例的原型
// name 接受的就是你要修饰的函数名
// descriptor 接受的是一个当前函数的描述对象, 是一个数据劫持形式(defineProperty)
descriptor.value = function () {
console.log(`我玩的是 ${ x }, 已经玩了 ${ y } 年了`)
}
}
}
// 不使用装饰器
class Student1 {
play () {
console.log('我喜欢玩的是 篮球, 足球, 羽毛球')
}
}
const s1 = new Student1()
s1.play() // 我喜欢玩的是 篮球, 足球, 羽毛球
// 使用装饰器
class Student2 {
@fn('TS', 3)
play () {
console.log('我喜欢玩的是 篮球, 足球, 羽毛球')
}
}
const s2 = new Student2()
s2.play() // 我玩的是 TS, 已经玩了 3 年了
●这里其实就是利用装饰器把函数给换掉了
类方法的参数装饰器
●这种装饰器就是用来修饰类身上的方法中的参数的
// 依旧是我书写的装饰器工厂
function fn(n: any) {
console.log('n : ', n)
return function (params: any, name: string, index: number) {
// params 接受的是当前的原型
// name: 函数名
// index: 索引位置
// 查看函数实参的个数
console.log('length : ', params[name].length)
}
}
●注意
○只能做监控参数是否传递, 没办法修改
○必须要使用装饰器工厂形式
○因为目前的装饰器机制还不是很完善
class Student {
play (
// 修饰参数, 就放在参数的前面
@fn(20)
n: number
) {
console.log('play 内的 n : ', n)
}
}
const s1 = new Student()
s1.play(100)
●输出结果
n : 20
length : 1
'play 内的 n' : 100
●说白了, 各种装饰器就是对对应的内容进行一些修饰而已
●目前还没有那么完善, 期待后期 TS 的更新和完善
●我相信完善以后的装饰器会是非常强大的存在
相关推荐
- C语言学习从内存堆栈视角,给这段枚举代码做个 "内存透视"
-
从内存堆栈视角,给这段枚举代码做个"内存透视"#include<stdio.h>enumDAY{MON=1,TUE,WED,THU,FR...
- Python基础:枚举,都有哪些特点和使用场景呢?
-
在Python编程语言中,枚举(Enumeration)是一种特殊的类,用于为一组常量创建一个名称空间。枚举类在Python3.4中被引入,提供了一种更加直观和方便的方式来处理一组相关的常量。枚举类...
- Java枚举你真的会用吗_java枚举怎么使用
-
概述Java中枚举,大家在项目中经常使用吧,主要用来定义一些固定值,在一个有限的集合内,比如在表示一周的某一天,一年中的四季等。那你了解枚举的本质吗?了解枚举的一些常见用法吗?枚举介绍和使用枚举主要用...
- 反射、枚举以及Lambda表达式_反射getmethod
-
一、反射1.定义Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法(即使是私有的);对于任意一个对象,都能够调用它的任意方法和属性,那么,我们就...
- 一个高效使用cursor开发项目的方法,怎么让 AI 写的代码不跑题?
-
最近又用cursor做了一个小应用,番茄时钟,用来管理自己的时间,提高效率。然后使用cursor开发的过程中。有了一些新的感悟。找到了一条可以让Curosr不跑题的办法。生成一份详细的项目资...
- 前端铜九铁十面试必备八股文——工程化
-
常用的git命令gitclone:克隆远程仓库到本地。gitinit:在当前目录初始化一个新的Git仓库。gitadd:将文件添加到暂存区,准备提交。gitcommit-m"co...
- IntelliJ IDEA 2025.2 的主要更新亮点
-
以下是该版本的一些关键改进与功能更新:AI增强体验离线Java代码补全:AI助手现在支持在离线模式下进行Java代码块建议,并允许用户选择本地代码模型使用。AIAssistant新增...
- 一行命令,AI 直接写代码!OpenAI 正式发布 Codex CLI
-
【一句话速读】OpenAI把2021年的Codex品牌复活,推出全新CodexCLI——一个本地运行的轻量级编码代理。只需npmi-g@openai/codex,它就能在终端里帮...
- 如何使用高级TypeScript模式构建可扩展的QA框架
-
TypeScript自动化QA(7部分系列)TypeScript第一步:自动化QA实用路线图如何在TypeScript中使用数组和对象构建强大的QA自动化脚本如何掌握TypeScript基础...
- Bun JS工具包新增MySQL驱动和密钥管理功能
-
Bun团队发布了其JavaScript打包器和运行时的1.2.21版本,该工具使用Zig语言编写,新增了包括MySQL和SQLite内置驱动、YAML解析器以及用于工具和本地开发的密钥管理器等功能。新...
- 编码 10000 个小时后,开发者悟了:“不要急于发布!”
-
【CSDN编者按】在软件开发的道路上,时间是最好的老师。根据“一万小时定律”,要成为某个领域的专家,通常需要大约一万小时的刻意练习。本文作者身为一名程序员,也经历了一万小时的编程,最终悟出了一个道理...
- 一文说明,TypeScript 的装饰器_typescript logo
-
●装饰器(Decorators)●注意:装饰器目前是一项实验性特性,在未来的版本中可能会发生改变●装饰器一般使用在以下几个地方○类○类属性○类方法○类方法的参数○通过这些我们也能看得出来,...
- 前端小哥哥:如何使用typescript开发实战项目?
-
前言笔者上一篇文章:主要写了typescript的用法和核心知识点总结,这篇文章将通过一个实际的前端案例来教大家如何在项目中使用typescript.你将收获如何使用umi快速搭建一个基于React...
- 一篇文章搞懂TypeScript_typescript implements
-
TypeScript是JavaScript的超集,一方面给动态类型的js增加了类型校验,另一方面扩展了js的各种功能。原始数据类型字符串数值布尔nullundefinedSymbolBi...
- TypeScript的any和unknown,用错一个就是线上Bug
-
在TypeScript开发中,类型系统是我们抵御运行时错误的第一道防线。但两个特殊类型——any和unknown,却常常被误用,成为线上故障的隐形推手。本文通过真实案例解析,告诉你为什么unknown...
- 一周热门
-
-
【验证码逆向专栏】vaptcha 手势验证码逆向分析
-
Python实现人事自动打卡,再也不会被批评
-
Psutil + Flask + Pyecharts + Bootstrap 开发动态可视化系统监控
-
一个解决支持HTML/CSS/JS网页转PDF(高质量)的终极解决方案
-
再见Swagger UI 国人开源了一款超好用的 API 文档生成框架,真香
-
网页转成pdf文件的经验分享 网页转成pdf文件的经验分享怎么弄
-
C++ std::vector 简介
-
飞牛OS入门安装遇到问题,如何解决?
-
系统C盘清理:微信PC端文件清理,扩大C盘可用空间步骤
-
10款高性能NAS丨双十一必看,轻松搞定虚拟机、Docker、软路由
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)