装饰器
概述
面向对象的概念(java:注解, c#:特征) angular中大量使用 react 中也会用到 目前js支持装饰器, 目前注意建议征集的第二阶段
解决的问题
装饰器 可以带来额外的信息量 分离关注点
- 信息书写位置的问题
- 重复代码的问题 上述两个问题产生的根源: 某些信息,在定义的时候, 能够附加的信息量有限
装饰器的作用: 为某些属性,类,参数,方法提供元数据信息(metadata)
装饰器的本质
在js中,装饰器是一个函数。 (装饰器是要参与运行的)
类装饰器
类装饰器的本质是一个函数,该函数接收一个参数,表示类本身(构造函数本身)
使用装饰器时@得到一个函数
在ts中如何约束一个变量为类
- Function 但是这种不能用 new 调用会报错
- new() => object
装饰器函数运行时间: 类定义后直接运行;
类装饰器可以具有返回值:
- void: 仅运行函数
- 返回一个新的类:会将新的类替换掉装饰目标
例子
/**
* @ClassDecorator
* 类装饰器
* @param targer 原型对象
*/
const doc : ClassDecorator = (target: any) => {
// console.log(target);
target.prototype.name = 'hahah'
}
/**
* @PropertyDecorator
* 属性装饰器
* @param target 原型对象
* @param key 属性名称
*/
const propertyDoc: PropertyDecorator = (target: any, key: string | symbol) => {
console.log('PropertyDecorator => ',target, key)
}
/**
* @ MethodDecorator
* 方法装饰器
* @param target 原型对象
* @param key 方法名称
* @param descriptor
* {
* value: [Function: getName],
* writable: true, 可写
* enumerable: false, 可枚举
* configurable: true 可配置
* }
*/
const methodDoc: MethodDecorator = (target: any, key: string | symbol, descriptor: any) => {
console.log('MethodDecorator =>',target, key, descriptor)
}
/**
* @ ParameterDecorator
* @param target
* @param key 函数名称
* @param index 参数所在位置,索引
*/
const paramsDoc: ParameterDecorator = (target: any, key: string | symbol | undefined, index: any) => {
console.log('ParameterDecorator => ', target, key, index);
}
@doc
class Lvxl {
@propertyDoc
public name: string
constructor() {
this.name = 'xixihaha'
}
@methodDoc
getName(@paramsDoc name: string, @paramsDoc age: string) {}
}
const ll = new Lvxl()
// PropertyDecorator => {} name
// ParameterDecorator => {} getName 1
// ParameterDecorator => {} getName 0
// MethodDecorator => {} getName {
// value: [Function: getName],
// writable: true,
// enumerable: false,
// configurable: true
// }
利用装饰器封装GET请求
import axios from "axios";
/**
* 封装get请求
* @param url
* @constructor
* 高阶函数
*/
const Get = (url: string) => {
return (target:any, key: string, descriptor: PropertyDescriptor) => {
// 读取执行函数
const fnc = descriptor.value
axios.get(url).then(res => {
fnc(res, {
status: 200,
success: true
})
}).catch(e => {
fnc(e, {
status: 500,
success: false,
})
})
}
}
class Controller {
constructor() {
}
@Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
getList(res: any, status: any) {
console.log(res.data, status)
}
}
// {
// code: 200,
// message: '成功!',
// result: {
// total: 14782,
// list: [
// [Object], [Object],
// [Object], [Object],
// [Object], [Object],
// [Object], [Object],
// [Object], [Object]
// ]
// }
// } { status: 200, success: true }