TypeScript 类方法装饰器

type ClassMethodDecorator = (value: Function,context: {kind: 'method';name: string | symbol;static: boolean;private: boolean;access: { get: () => unknown };addInitializer(initializer: () => void): void;}
) => Function | void;

1、如果装饰器返回一个函数就会替代装饰的函数

function replaceMethod(originMethod: Function,content: ClassMethodDecoratorContext
) {return function (...args) {console.log(args);originMethod.call(this, args);};
}

2、装饰器可以传参数

@replaceMethod('7777')
myMethodfunction replaceMethod(...args) {return function (originMethod: Function,content: ClassMethodDecoratorContext) {return function (...hello) {originMethod.call(this,hello);};};
}
装饰器接参数重新类中的方法 停留时间执行
function Greeter(value: any, context: any) {}function replaceMethod(num: number) {return function (originMethod: Function,content: ClassMethodDecoratorContext) {return function (...hello) {setTimeout(() => {originMethod.call(this, hello);}, num);};};
}@Greeter
class User {[propertyName: string]: any;name: string;constructor(name: string) {this.name = name;}@replaceMethod(1000)hello(u) {console.log("元旦快乐" + " " + this.name + u);}
}let u = new User("zhansan");
u.hello("0999");

3、方法装饰器的 { addInitializer } 相当于constructor 初始化对象 参数是一个函数,可以访问当前this

function initialInstance(originMethod: Function,content: ClassMethodDecoratorContext
) {content.addInitializer(function () {this[content.name] = this[content.name].bind(this);});
}
class Person {name: string;constructor(name: string) {this.name = name;// greet() 绑定 this// this.greet = this.greet.bind(this);}@initialInstancegreet() {console.log(`Hello, my name is ${this.name}.`);}
}

4、一个方法可以有多个装饰器


/**** @param originMethod @type {Function}* @param content  @type {ClassMethodDecoratorContext}*/
function collectMethods(originMethod: Function,{ addInitializer, name }: ClassMethodDecoratorContext
) {addInitializer(function () {let _this = this as Person;if (!_this.collectMethodSet) {_this.collectMethodSet = new Set();}_this.collectMethodSet.add(name);});
}
function initialInstance(originMethod: Function,content: ClassMethodDecoratorContext
) {content.addInitializer(function () {this[content.name] = this[content.name].bind(this);});
}
class Person {name: string;constructor(name: string) {this.name = name;}[p: string]: any;@initialInstance@collectMethodsgreet() {console.log(`Hello, my name is ${this.name}.`);}@collectMethodshandle() {}
}const g = new Person("张三");
g.greet() //Hello, my name is 张三
console.log(g.collectMethodSet); //Set(2) { 'greet', 'handle' }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/589297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 中 async/await 遇上 forEach 两种写法,是否按照遍历?

在 C# 中,async/await 与 forEach 可以搭配使用,但需要注意的是,forEach 本身不是一个异步操作,它会按顺序同步地遍历集合中的元素,并将每个元素作为参数传递给回调函数。因此,如果在 forEach 循环中使用 a…

【嵌入式开发 Linux 常用命令系列 7.3 -- linux 命令行数值计算】

文章目录 linux 命令行数值计算使用 awk使用 bc 命令使用 Bash 的内置算术扩展使用 expr脚本命令实现 linux 命令行数值计算 在 Linux 命令行中,您可以使用多种方法来执行基本的数学运算。以下是一些示例: 使用 awk awk 是一个强大的文本处理工具&…

【C#】知识点实践序列之Lock的输出多线程信息

大家好,我是全栈小5,欢迎来到《小5讲堂之知识点实践序列》文章。 2023年第2篇文章,此篇文章是C#知识点实践序列之Lock知识点,博主能力有限,理解水平有限,若有不对之处望指正! 本篇在Lock锁定代码…

CAN,SPI,IIC,USART每帧的组成

字节是计算机中用于存储数据的基本单位,一个字节由8个二进制位组成。在计算机科学中,字节的大小是固定的,即1字节8位。1比特1位 在不同的数据类型中,字节的大小也不同。例如,在ASCII码中,一个英文字母或数…

【python_数据分组】

对excel按照标签进行分组,例如按照“开票主体和对方公司”进行分组,并获取对应的明细。 表格如下: def main(excel_data):result {}for d in excel_data:if str(d[0])str(d[1]) in result:result[str(d[0])str(d[1])].append([d[0],d[1],…

Java 语法糖的介绍

在Java编程中,语法糖是一种简化代码的技巧,它可以使代码更易读、易写,同时提高开发效率。尽管从语法上看,它更像是一种装饰,但它能给我们的代码带来革命性的改变。 一、什么是Java语法糖? "语法糖&q…

删除重复字符

本题要求编写程序,将给定字符串去掉重复的字符后,按照字符ASCII码顺序从小到大排序后输出。 输入格式: 输入是一个以回车结束的非空字符串(少于80个字符)。 输出格式: 输出去重排序后的结果字符串。 输…

leetcode每日一题42

107.二叉树的层序遍历II 就层序遍历后reverse一下 class Solution { public:vector<vector<int>> levelOrderBottom(TreeNode* root) {queue<TreeNode*> que;if(root!nullptr)que.push(root);vector<vector<int>> result;while(!que.empty()){…

web component - 使用HTML Templates和Shadow DOM构建现代UI组件

Web Component是一种用于构建可重用的UI组件的技术。它使用标准化的浏览器API&#xff0c;包括Custom Elements、Shadow DOM和HTML Templates来实现组件化开发方式。这些API都是现代浏览器原生支持的&#xff0c;因此不需要引入第三方库或框架即可使用。 在这篇博客中&#xf…

[Verilog] 加法器(半加法器 | 全加法器 | 串行加法器 | 并行加法器 | 十进制加法器)详解

前言 在数字电路中,加法器是一种常见的逻辑电路,用于将两个数字相加。本文将介绍如何使用Verilog实现各种加法器。 1 加法器种类 整数加法器 半加器(Half Adder):它是最简单的加法器,只能进行两个输入位的相加操作,不包括进位位。全加器(Full Adder):它是最基本的加…

第6课 用window API捕获麦克风数据并加入队列备用

今天是2024年1月1日&#xff0c;新年的第一缕阳光已经普照大地&#xff0c;祝愿看到这篇文章的所有程序员或程序爱好者都能在新的一年里持之以恒&#xff0c;事业有成。 今天也是我加入CSDN的第4100天&#xff0c;但回过头看一看&#xff0c;这么长的时间也没有在CSDN写下几篇…

SpringCloud-高级篇(九)

&#xff08;1&#xff09;Seata高可用 我们学习了Seata的各种用法了&#xff0c;Seata的服务是单节点部署的&#xff0c;这个服务如果挂了&#xff0c;整个事务都没有办法完了&#xff0c;下面我们学习Seata的高可用的知识。 实现高可用&#xff0c;还是比较简单&#xff0c;…

UntiyShader(六)Unity提供的Cg/HLSL语义

目录 前言 一、什么是语义(Semantics) 系统数值语义(system-value semantics) 二、Unity

QT上位机开发(抽奖软件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 用抽奖软件抽奖&#xff0c;是一种很常见的抽奖方式。特别是写这篇文章的时候&#xff0c;正好处于2023年12月31日&#xff0c;也是一年中最后一天…

【华为机试】2023年真题B卷(python)-喊七的次数重排

一、题目 题目描述&#xff1a; 喊7是一个传统的聚会游戏&#xff0c;N个人围成一圈&#xff0c;按顺时针从1到N编号。 编号为1的人从1开始喊数&#xff0c;下一个人喊的数字为上一个人的数字加1&#xff0c;但是当将要喊出来的数字是7的倍数或者数字本身含有7的话&#xff0c;…

ceph之rados设计原理与实现:crush算法

执行命令 ceph osd crush dump可以查看当前集群crush信息 其中会输出可调crush参数"tunables"、规定的若干规则"rules"、以及crush map。 这些规则"rules"可以与存储池绑定&#xff0c;针对特定存储池执行自制的crush算法映射。 "crushmap…

新手快速上手掌握基础排序<二>快速排序快速入门

目录 引言 一&#xff1a;快速排序qsort的简介 1.qsort是一个库函数 2.库函数的查询了解方法 3.qsort的具体使用方法 4.qsort函数使用的一些注意点 5.qsort函数的特点 6.代码实现 (1)整数数组的快速排序 &#xff08;2&#xff09;结构体的快速排序&#xff08;学…

NumPy 中级教程——线性代数操作

Python NumPy 中级教程&#xff1a;线性代数操作 NumPy 提供了丰富的线性代数操作功能&#xff0c;包括矩阵乘法、行列式计算、特征值和特征向量等。这些功能使得 NumPy 成为科学计算和数据分析领域的重要工具。在本篇博客中&#xff0c;我们将深入介绍 NumPy 中的线性代数操作…

使用.Net nanoFramework 驱动ESP32的OLED显示屏

本文介绍如何使用.Net nanoFramework 驱动ESP32的OLED显示屏。我们将会从最基础的部分开始&#xff0c;逐步深入&#xff0c;让你能够理解并实现整个过程。无论你是初学者还是有一定经验的开发者&#xff0c;这篇文章都会对你有所帮助。 1. 硬件准备 1.1 ESP32开发板 这里我们…

samba的基础运用和配置

#主页传送门&#xff1a;江南的江 #每日鸡汤&#xff1a;落魄不是你吃不上饭&#xff0c;不是没人理你。只是你一方面在意别人的目光&#xff0c;另一方面却不清楚自己的方向在哪里。 #music 推荐&#xff1a;没有理想的人不伤心(新裤子) #初心和目标&#xff1a;在网络安全搞出…