Skip to main content

装饰器

概述

面向对象的概念(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 }