装饰器文档
目录
思维导图

基本理论
定义
- 装饰器就是一个方法或者叫函数,可以写到到类、方法、属性、参数,对象上,基于原有基础上扩展其功能。
为什么要用
- 从规范来讲,尽量少用继承,优先用对象进行扩充。
- 关键点在于切面:其由切点和增强点组成:类比于 before after.
- 为前端补充了 AOP 面向切面编程思想:

function log(target: any, key: string, descriptor: PropertyDescriptor) {
const oldValue = descriptor.value
descriptor.value = function () {
console.log(`记录日志...`)
return oldValue.apply(this, arguments)
}
}
class Foo {
@log
fn1() { console.log('业务功能1') }
}
const f = new Foo()
f.fn1()
- 监控系统(性能,错误,行为分析)。
- 前置拦截以及后置拦截:执行原有函数前,做一些事情,执行原有函数后,还需要做一些事情
执行时机
- 编译阶段就执行了。所以说装饰器函数真正能触及到的,就只有类这个层面上的对象(类的原型对象):
function FirstClassDecorator1(targetClass:any ) {
let targetClassObj = new targetClass();
targetClassObj.buy();
console.log("targetClass.name:", targetClass.name);
}
@FirstClassDecorator1
class CustomerService {
name: string = "下单"
constructor() {
}
buy() {
console.log(this.name + "购买");
}
placeOrder() {
console.log(this.name + "下单购买");
}
}
弊端
- 函数式组件会出现函数提升的问题:高阶组件解决;
function doSomething(name) {
console.log('Hello, ' + name);
}
function loggingDecorator(wrapped) {
return function() {
console.log('Starting');
const result = wrapped.apply(this, arguments);
console.log('Finished');
return result;
}
}
const wrapped = loggingDecorator(doSomething);
- 多层装饰器会加大项目复杂度
设计原则
- 单一指责:每个装饰器只扩展一个功能。
- 以及开放封闭原则:仅仅对现有功能进行扩展,新旧逻辑解耦。
本质
- 就是函数,也是 @ 符的语法糖。
分类
- 类装饰器、属性装饰器、方法装饰器、参数装饰器,元数据装饰器
前端应用
react-redux
AOP
- 优势:非侵入式。
Angular
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-product-alerts',
templateUrl: './product-alerts.component.html',
styleUrls: ['./product-alerts.component.css']
})
export class ProductAlertsComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
项目应用
- 为什么要用:旧有添加逻辑自定义属性 id,针对特定的组件需要改动源代码,同时对于纯自定也业务组件,难以支持打标签。
- 能够解决什么问题:首先符合开放封闭原则,形成通用解决方案,避免特定组件,差异处理。
- 初版方案:装饰器指责:能够精准在目标标签上打上 id,监控 sdk 负责埋点,上报用户信息,不再让装饰器承担过多的职责。
作业:
- 证明各个装饰器的执行步骤:证明至少三个:多个装饰器同时存在,其先后顺序。
- 不限制版本。