装饰器定义
- 装饰器是一种特殊类型的声明,它能够被附加到类声明、方法、属性或参数上,可以修改类的行为
- 常见的装饰器有类装饰器、属性装饰器、方法装饰器和参数装饰器
-
类装饰器
类装饰器在类声明之前声明,用来监控、修改或替换类定义
- 参数是类的定义或者构造函数
代码示例
基本的装饰器
export {};// 类的装饰器,参数target是类的构造函数本身interface Animal {swings: number;fly: () => {};}function flyable(target: any) {console.log(target);target.prototype.swings = 2;target.prototype.fly = function () {console.log("我能飞");};}@flyableclass Animal {constructor() {}}let animal: Animal = new Animal();console.log(animal.swings);animal.fly();
类的装饰器工厂
// 类的装饰器工厂,可以传递不同参数值,参数target是类的构造函数本身interface Animal {swings: number;fly: () => {};}function flyable(swings: number) {return function flyable(target: any) {console.log(target);target.prototype.swings = swings;target.prototype.fly = function () {console.log("我能飞");};};}@flyable(4)class Animal {constructor() {}}let animal: Animal = new Animal();console.log(animal.swings);animal.fly();
多种类型的装饰器方法
// 实例属性的装饰器,target是类原型对象,key是属性的名字function instancePropertyDecorator(target, key) {target.protoName = "这是类实例上的属性";console.log("instancePropertyDecorator", target, key);}// 类的静态属性,target是类的构造函数,key是属性名function classPropertyDecorator(target, key) {console.log("classPropertyDecorator", target, key);}// 实例方法,target是类的原型,key是方法名,descriptor属性描述符function instanceMethodDecorator(target, key, descriptor) {console.log("instanceMethodDecorator", target, key, descriptor);}function classMethodDecorator(target, key, descriptor) {console.log("classMethodDecorator", target, key, descriptor);}interface Person {instanceProperty: string;protoName: string;}class Person {// 实例的属性装饰器// 实例的属性装饰器@instancePropertyDecoratorinstanceProperty!: string; //实例属性//实例属性// 类的属性装饰器@classPropertyDecoratorstatic classProperty: string; //类的静态属性// 实例的方法装饰器@instanceMethodDecoratorinstanceMethod() {//实例的方法}// 类的方法装饰器@classMethodDecoratorclassMethod() {}}let p = new Person();console.log(Person.prototype.protoName);console.log(p.protoName);
数据埋点的运用
function before(beforeFn) {return function (target, methodName, descriptor) {let oldMethod = descriptor.value;descriptor.value = function () {beforeFn.apply(this, arguments);return oldMethod.apply(this, arguments);};};}function after(afterFn) {return function (target, methodName, descriptor) {let oldMethod = descriptor.value;descriptor.value = function () {let result = oldMethod.apply(this, arguments);afterFn.apply(this, arguments);return result;};};}class App extends Component {@before(() => console.log("before"))onClickBefore() {console.log("beforeClick");}@after(() => console.log("after"))onClickAfter() {console.log("afterClick");}@after(() => fetch("/api/json"))ajaxClick() {console.log("ajax data");}render() {return (<div><button onClick={this.onClickBefore}> beforeClick</button><button onClick={this.onClickAfter}>afterClick</button></div>);}}
表单数据校验的运用
// 表单校验Function.prototype.before = function (beforeFn) {let thisFn = this;return function () {let pass = beforeFn();if (pass) {thisFn.apply(this, arguments);}};};function registerFn(event) {console.log("提交表单");}registerFn = registerFn.before(function () {let username = document.getElementById("username").nodeValue;if (!username) {return alert("用户名有无");}return true;});
