LoggerTest
import { LoggerClass, LoggerMethod, LoggerParams, LoggerProperty } from './LoggerDescriptor'
@LoggerClass
class LoggerTest {
@LoggerProperty
private readonly info: string
constructor (private readonly key: string) {
this.info = 'test'
}
@LoggerMethod
public getLoggerInfo () {
console.log(this.info, this.key)
}
public setLoggerInfo (@LoggerParams key: string) {
console.log(key)
}
private maxValue () {
}
}
const loggerTest = new LoggerTest('key')
loggerTest.getLoggerInfo()
loggerTest.setLoggerInfo('info')
注解&装饰器
类装饰器
介绍:装饰器是指接受一个类构造函数作为参数的函数,并且返回undefined、参数中提供的构造函数或一个新的构造函数。返回undefined 等同于返回参数中提供的构造函数
const LoggerClass = function (target: any) {}
export const LoggerClass = function (target: any) {
const original = target
function construct (constructor: any, args: any) {
let innerConstruct: any = function () {
return constructor.apply(original, args)
}
innerConstruct.prototype = constructor.prototype
return new innerConstruct()
}
let proxy: any = function(...args: any[]){
return construct(original, args)
}
proxy.prototype = original.prototype
return proxy
}
方法装饰器
介绍:方法装饰器函数是一个接受三个参数的函数。
- 这个属性的对象
- 属性名 方法名
- 一个可选参数,属性的描述对象
export const LoggerMethod = function (target: any, key: string, descriptor: any) {}
export const LoggerMethod = function (target: any, key: string, descriptor: any) {
const originMethod = descriptor.value
descriptor.value = function (...args: any[]) {
const result = originMethod.apply(this, args)
console.log('result', key, args, result)
return result
}
}
属性装饰器
介绍:方法装饰器函数是一个接受三个参数的函数。
- 这个属性的对象
- 属性名 方法名
不需要返回一个属性描述对象
export const LoggerProperty = function (target: any, key: string) {}
export const LoggerProperty = function (target: any, key: string) {
let original = target[key]
const getter = () => {
return original
}
const setter = (newval: string) => {
original = newval
}
if(delete target[key]){
Object.defineProperty(target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true
})
}
}
参数装饰器
介绍:方法装饰器函数是一个接受三个参数的函数。
- 这个属性的对象
- 属性名 方法名
- 参数在参数列表中的索引位置
这个装饰器的返回值会被忽略
export const LoggerProperty = function (target: any, key: string) {}
export const LoggerParams = function (target: any, key: string, index: number) {
const originMethod = target[key]
target[key] = function (...args: any[]) {
console.log(args[index])
originMethod.apply(this, args)
}
}
完整示例
export const LoggerClass = function (target: any) {
const original = target
function construct (constructor: any, args: any) {
let innerConstruct: any = function () {
return constructor.apply(original, args)
}
innerConstruct.prototype = constructor.prototype
return new innerConstruct()
}
let proxy: any = function(...args: any[]){
return construct(original, args)
}
proxy.prototype = original.prototype
return proxy
}
export const LoggerMethod = function (target: any, key: string, descriptor: any) {
const originMethod = descriptor.value
descriptor.value = function (...args: any[]) {
const result = originMethod.apply(this, args)
console.log('result', key, args, result)
return result
}
}
export const LoggerProperty = function (target: any, key: string) {
let original = target[key]
const getter = () => {
return original
}
const setter = (newval: string) => {
original = newval
}
if(delete target[key]){
Object.defineProperty(target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true
})
}
}
export const LoggerParams = function (target: any, key: string, index: number) {
const originMethod = target[key]
target[key] = function (...args: any[]) {
console.log(args[index])
originMethod.apply(this, args)
}
}
export const LoggerAny = function (...args: any[]) {
const that = args[0]
switch (args.length) {
case 1:
return LoggerClass.call(that, args[0])
case 2:
LoggerProperty.call(that, args[0], args[1])
break
case 3:
if (typeof args[2] === 'number') {
LoggerParams.call(that, args[0], args[1], args[2])
} else {
LoggerMethod.call(that, args[0], args[1], args[2])
}
break
default:
throw new Error('Descriptors are not valid here!')
}
}