ts的装饰器
console.log('装饰器.......') // 装饰器就是一个方法,可以注入到类,方法,属性上来拓展类,属性,方法,参数的功能 // 常见:类装饰器,属性装饰器,方法装饰器,参数装饰器 // 写法:1.普通装饰器(无法传参) 2.装饰器工厂(可传参) // 1.类装饰器 // 类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。 // 普通装饰器(无法传参) function logClass(params: any) { console.log(params) // 通过原型链拓展类,属性,方法,参数 params.prototype.apiUrl = 'xxx' params.prototype.run = function () { console.log('run...........') } } @logClass class HttpClient { constructor() {} getData() {} } let http: any = new HttpClient() console.log(http) http.run() // 装饰器工厂(可传参) function logClass1(params: string) { return function (target: any) { console.log(params) console.log(target) target.prototype.apiUrl = params } } @logClass1('hello') class HttpClient1 { constructor() {} getData() {} } let http1: any = new HttpClient1() console.log(http1) // 重载构造函数 function logClass2(target: any) { return class extends target { api: any = 'api2222' getData() { console.log(this.api + '333') } } } @logClass2 class HttpClient2 { public api: string | undefined constructor() { this.api = 'api11111' } getData() { console.log(this.api) } } let http2: any = new HttpClient2() console.log(http2) http2.getData() // 2.属性装饰器 // 属性装饰器表达式会在运行时被当作函数调用 // 接收两个参数 // 1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象 // 2. 成员的名字 // 类装饰器 function logClass3(params: string) { return function (target: any) { // console.log(params) // console.log(target) target.prototype.apiUrl = params } } // 属性装饰器 function logProperty(params: string) { return function (target: any, attr: any) { // console.log(params) // console.log(target) target[attr] = params } } @logClass3('hello33333') class HttpClient3 { @logProperty('hello4444') public api: any | undefined constructor() {} getData() {} } let http3: any = new HttpClient3() console.log(http3) // 3.方法装饰器 // 应用在方法的属性描述上,可以用来监视、修改、替换方法定义 // 接收三个参数 // 1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象 // 2. 成员的名字 // 3. 成员的属性的描述 function logClass4(params: string) { return function (target: any, methodsName: any, desc: any) { console.log(target) console.log(methodsName) console.log(desc) console.log(desc.value) let o = desc.value desc.value = function (...args: any[]) { args = args.map((item) => { return String(item) + params }) o.apply(this, args) } } } class HttpClient4 { public api: any | undefined constructor() {} @logClass4('方法装饰器方法装饰器方法装饰器方法装饰器') getData(...args: any[]) { console.log(args) console.log('getDatagetDatagetData') } } let http4: any = new HttpClient4() http4.getData(123, 'xxx') // 4.参数装饰器 // 参数装饰器表达式会在运行时当作函数被调用,可以使参数装饰器为类的原型增加一些元素数据 // 1. 对于静态成员是类的构造函数,对于实例成员是类的原型对象 // 2. 参数的名字 // 3. 参数索引 function logClass5(params: string) { return function (target: any, methodsName: any, desc: any) { console.log(target) console.log(methodsName) console.log(desc) } } class HttpClient5 { public api: any | undefined constructor() {} getData(@logClass5('参数装饰器参数装饰器') uuid: any) { console.log(uuid) } } let http5: any = new HttpClient5() http5.getData(1232123) // 装饰器执行顺序 // 属性>方法参数>方法>>类 // 存在多个同样装饰器则是从下到上执行 function logClass6(params: string) { return function (target: any, methodsName: any, desc: any) { console.log(params) } } function logClass7(params: string) { return function (target: any, methodsName: any, desc: any) { console.log(params) } } function logClass8(params: string) { return function (target: any, methodsName: any, desc: any) { console.log(params) } } function logClass9(params: string) { return function (target: any, methodsName: any, desc: any) { console.log(params) } } function logClass10(params: string) { return function (target: any) { console.log(params) } } function logClass11(params: string) { return function (target: any, attr: any) { console.log(params) } } @logClass10('类装饰器装饰器') class HttpClient6 { @logClass11('属性装饰器') public api: any | undefined constructor() {} @logClass8('方法装饰器装饰器1') @logClass9('方法装饰器装饰器2') getData( @logClass6('参数装饰器1') uuid1: any, @logClass7('参数装饰器2') uuid2: any ) { console.log(uuid1) console.log(uuid2) } } let http6: any = new HttpClient6() http6.getData(1232123, 234)