设计模式:装饰器
概念:装饰器作用是在在不会影响原有方法或类的功能的前提下,对它们进行增强。 属于AOP面向切面编程下的一种设计方案,更“优雅”地把“辅助功能逻辑”从“业务逻辑”中分离。( 比如将日志记录,性能统计,安全控制,异常处理等代码从业务逻辑代码中解耦出来出来)。
本质:装饰器语法本质是 Object.defineProperty,装饰器是基于Object.definePropert的语法糖。
Object.defineProperty(obj, prop, descriptor)
- 第一个参数是要装饰的对象target
- 第二个参数是对象的属性名key
- 第三个参数是该属性的描述对象descriptor
/**
* {
* configurable: true, // 可配置的
* enumerable: true, // 可枚举的
* value: () => {}, // 该属性对应的值(数值,对象,函数,正则,日期等)
* writable: true, // 可写入的
* }
*/
var a = { b: () => {} }
var descriptor = Object.getOwnPropertyDescriptor(a, 'b')
console.log(descriptor)
五种装饰器
属性装饰器
type PropertyDecorator = (target: Object, propertyKey: string | symbol) => any;
let nameDecorator: PropertyDecorator = (target, propertyKey) => {
const descriptor: PropertyDescriptor = {
writable: true,
};
return descriptor
}
方法装饰器:(作用在类的方法上)
接受 target,name,descriptor 三个参数
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
value?: any;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
// tyoe 实现
type MethodDecorator = (target: Object,name: PropertyKey,descriptor: PropertyDescriptor) =>PropertyDescriptor;
//interface 实现
interface MethodDecorator2{
(target: Object,name: string|symbol,descriptor: PropertyDescriptor):PropertyDescriptor
}
实现日志模块
let log = (type:string):MethodDecorator2 => {
return (target, name, descriptor) => {
const method = descriptor.value;
descriptor.value = (...args) => {
console.info(`(${type}) 正在执行: ${name}(${args}) = ?`);
let ret;
try {
ret = method.apply(target, args);
console.info(`(${type}) 成功 : ${name}(${args}) => ${ret}`);
} catch (error) {
console.info(`(${type}) 失败: ${name}(${args}) => ${error}`);
}
return ret;
}
return descriptor
}
}
class IronMan {
@log('IronMan 自检阶段')
check(){
return '检查完毕';
}
@log('IronMan 攻击阶段')
attack(){
return '击倒敌人';
}
@log('IronMan 机体报错')
error(){
throw 'Something is wrong!';
}
}
var tony = new IronMan();
tony.check();
tony.attack();
类装饰器:(作用在类上 decorator)
hoc
function hocComponent(namespace) {
return WrappedComponent => {
return class extends React.Component {
constructor(props) {
super(props);
}
render() {
const pp= Object.assign({}, this.props, {
name: namespace
});
return <div>
<WrappedComponent {...pp} />
<div>{namespace}</div>
</div>;
}
componentWillUnmount() {
}
};
};
}
// 装饰组件
@hocComponent('eventSpace')
class Dashboard extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div>222{this.props.name}3</div>;
}
}
export default Dashboard;
作用在类上的 decorator, 接受一个target 参数是类本身,从而对类添加静态属性
// 这里的 `target` 是类本身
function doge (target) {
target.isDoge = true
}
@doge
class Dog {}
console.log(Dog.isDoge)
// true

浙公网安备 33010602011771号