装饰器
前言
angularjs运用装饰器会比较多,它也是ts的一大特性,下面知识能够让大家对ts装饰器有一个初步的了解.
基础知识
装饰器:本质是一个方法,可以注入到类、方法、属性参数上来拓展类、属性、方法、参数的功能.
分类:类装饰器、属性装饰器、方法装饰器、方法参数装饰器.
装饰器的写法:普通装饰器(无法传参)、装饰器工厂(可传参).
各种装饰器执行顺序:属性装饰器 > 方法参数装饰器 > 方法装饰器 > 类装饰器;如果每种有多个,则从后往前执行
类装饰器
在不修改当前类的前提下,动态给类添加属性和方法
// 普通装饰器(无法传参)
function Log(target: any) {
// console.log(target)
// target 代表当前类
target.prototype.apiUrl = 'http://www.api.com'
target.prototype.send = function() {
console.log(`send invoke`)
}
}
// 装饰器工厂(可传参)
function LogFactory(params: any) {
return function(target: any) {
// console.log(target)
// console.log('------')
// console.log(params)
target.prototype.apiUrl = params.apiUrl
}
}
// 普通装饰器(重写构造器方法或是其它方法)
function LogOverride(target: any) {
return class extends target {
apiUrl = 'http://baidu.com'
getData() {
console.log('重写后的apiUrl:', this.apiUrl)
}
}
}
//@Log //普通装饰器(无法传参)
// @LogFactory({apiUrl: 'http://baidu.com'})
@LogOverride
class HttpClient1 {
public apiUrl: string | undefined
constructor() {
this.apiUrl = 'http://baidu.com'
}
getData() {
console.log(this.apiUrl)
}
}
const httpClient1: any = new HttpClient1()
httpClient1.getData()
// console.log(httpClient1)
// console.log(httpClient1.apiUrl)
// httpClient1.send()
属性装饰器:
接收两个参数:
- 参数1 类的构造函数(静态成员)/原型对象(实例成员)
- 参数2 成员的名字
function Property(params: string) {
// 参数1 类的构造函数(静态成员)/原型对象(实例成员) prototype === HttpClient2.prototype
// 参数2 成员的名字
return function(prototype: any, name: string) {
prototype[name] = params
}
}
class HttpClient2 {
@Property('http://baidu.com')
public apiUrl: string | undefined
getData() {
console.log('apiUrl is ', this.apiUrl)
}
}
const httpClient2 = new HttpClient2()
httpClient2.getData()
方法装饰器
接收三个参数:
- 参数1 类的构造函数(静态成员)/原型对象(实例成员)
- 参数2 方法的名字
- 参数3 方法描述
// 方法装饰器
function Method(params: string) {
// 参数1 类的构造函数(静态成员)/原型对象(实例成员) prototype === HttpClient3.prototype
// 参数2 方法的名字
// 参数3 方法描述
return function(prototype: any, name: string, desc: any) {
// desc.value === getData
// console.log(desc)
// 保存之前的方法
const oldMethod = desc.value
desc.value = function(...args: any) {
args = args.map((item: any) => {
return String(item)
})
console.log('方法装饰器内部 ', args)
// console.log('method invoke start -----', new Date() - 0)
oldMethod.apply(this, args)
// console.log('method invoke end -----', new Date() - 0)
}
}
}
// 方法参数装饰器
function MethodParams(params: any) {
/**
* 参数1 类的构造函数(静态成员)/原型对象(实例成员)
* 参数2 方法的名字
* 参数3 参数的索引
*/
return function(prototype: any, name: string, index: number) {
console.log('---------------------------------------')
console.log(params)
console.log(prototype)
console.log(name)
console.log(index)
}
}
class HttpClient3 {
@Method('xxx')
getData(...args: any[]) {
console.log('getData method invoke', args)
}
setData(
@MethodParams('name') name: string,
@MethodParams('age') age: number
) {
console.log(`this person name is ${name} age is ${age}`)
}
}
const httpClient3 = new HttpClient3()
httpClient3.getData(123, 'nihao', true)
httpClient3.setData('zhangsan', 31)
版权声明:本文为qq_44855897原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。