最近想看angular,好像有这部分的内容,以前没学,索性学一下
修饰器专门修饰ts的类
修饰器本身是一个函数,使用@方式进行调用
1.普通修饰器
普通修饰器本质上是通过类的prototype来添加一些属性,个人觉得这样的写法有些万能
下面是一个例子,我要在类上添加name和sayname方法
// 调用装饰器
@putong
class Person1 {
constructor() {
}
}
// 这个any类型非常重要
let me: any = new Person1()
class Person2 {
constructor() {
}
}
let me1: any = new Person2()
let putongfunc = () => {
console.log("me.name", me.name);
me.sayname()
// console.log("me1.name", me1.name);//undefined
// 这就是这个ts的修改器只适用于@putong下的第一个定义的class
}
putongfunc()
2.装饰器工厂
普通装饰器的升级版,就多了一个传入的参数,定义起来比较优雅
function gongchang(str: string): (x: any) => void {
// 上面两个就是你自己定义的参数
// 下面这个才是真正的修饰器部分
return function (constructor: any): void {
constructor.prototype.hobby = str
constructor.prototype.sayhobby = function () {
console.log(this.hobby)
}
}
}
@gongchang("赚钱")
class Person3 {
constructor() {
}
}
let p: any = new Person3()
let gongchangfunc = () => {
console.log("hobby is:", p.hobby);
p.sayhobby()
}
gongchangfunc()
3.属性修饰器
用于设定一些属性,和普通修饰器功能有部分重叠,但是写法不一样
当然也是一个工厂修饰器的写法,毕竟带参数的都是这个写法
但是在写的时候遇到可一些小问题,我是在vue3里面实验的,不知道是我写错了还是怎么回事,一直返回undefined,但是当我复制在ts官网的playground上面时,确实起作用的
function shuxing(str: string): (a: any, b: string) => void {
return function (target: any, attr: string) {
target[attr] = str
}
}
class Person4 {
@shuxing("huanfeng")
public name: string | undefined
constructor() {
}
}
let p1: any = new Person4()
let shuxingfunc = () => {
// 暴露出p1的name属性
console.log(p1.name);
}
shuxingfunc()
4.方法装饰器
用来取代方法或者控制读取,类似有些文章里的访问装饰器,不过访问控制也可以通过普通装饰器实现,使用defineProperty方法
// 方法装饰器
function fangfa() {
return function (target: any, funcname: string, des: PropertyDescriptor) {
// 打印一下三个参数
console.log(target, funcname, des);
// 通过设置这个value属性可以替换修饰器下的第一个函数,也就是方法劫持
// 这个des就是defineProperty的那四个属性,应该可以通过这个来控制enumerable之类的属性,我在下面尝试一下
des.value = function () {
console.log("还是我黄烽最牛逼");
}
}
}
// 方法装饰器的第二种用法,其实是一种延伸
function cannumerable(t: boolean) {
return function (target: any, funcname: string, des: PropertyDescriptor) {
des.enumerable = t //默认是不能遍历的
}
}
class Person5 {
name: string = "huanfeng"
constructor() {
}
@fangfa()
@cannumerable(true)
sayname() {
console.log("鄙人不善奔跑");
}
}
let p2 = new Person5()
let fangfafunc = () => {
p2.sayname()//"还是我黄烽最牛逼" 这样的话能实现方法劫持
}
let fangfafunc1 = () => {
for (let k in p2) {
console.log(k);
}
}
5.参数修饰器
// 参数装饰器,很明显和函数的参数有关
// 我看了csdn的一些例子,没什么营养,实在不知道这个参数装饰器的用法,所以就不写了