1。什么是装饰器装饰器是一种特殊类型的声明,可以附加到类声明、方法、访问器、属性和参数上。装饰器是一个表达式。表达式执行后,返回一个函数。该函数的输入参数是:目标、名称和描述符。函数执行后,可能会返回一个描述符对象,用于配置目标对象装饰器使用@expression形式,并对表达式进行求值,最后必须返回一个函数,在运行时调用,并且修饰声明信息作为参数传入。例如://定义装饰器函数testDecorator(target:any,key:string):void{console.log("Target:",target);console.log("key:",key);}//使用decoratorclassBoat{color:string="yellow";getformattedColor():string{return`thisboatcoloris${this.color}`;}@testDecoratorpilot():void{console.log("swish");}}//实例化constboat=newBoat();boat.pilot();console.log(boat.formattedColor);运行得到:Target:{}key:pilotswishthisboatcolorisyellow2.装饰器的分类装饰器根据装饰的类型分为以下几种:命令行或tsconfig.json中的选项:命令行:tsc--targetES5--experimentalDecoratorsstsconfig.json:{"compilerOptions":{"target":"ES5","experimentalDecorators":true}}2.1类装饰器类装饰器用于类构造函数以监视、修改或替换类定义,并在类声明之前声明(紧挨着类声明)。请记住:类装饰器不能在声明文件(.d.ts)中使用,也不能在任何外部上下文中使用。类装饰器表达式在运行时作为函数调用,类构造函数作为其唯一参数。如果类装饰器返回一个值,它会用提供的构造函数替换类声明。如果要返回一个新的构造函数,则必须处理原始原型链。装饰器调用逻辑不会在运行时为您执行此操作。类装饰器声明:declaretypeClassDecorator=(target:TFunction)=>TFunction|void;顾名思义,类装饰器用于装饰类。它接收一个参数:target:TFunction-装饰类栗子://类装饰器functionclassDecorator(constructor:typeofBoat){console.log(constructor);}//使用类装饰器@classDecoratorclassBoat{}运行结果:[classBoat]2.2方法装饰器方法装饰器用于方法的属性描述符,可以监视、修改或替换方法定义,在要装饰的方法声明之前进行声明。方法装饰器不能在声明文件(.d.ts)、重载或任何外部上下文中使用。方法装饰器表达式在运行时会作为一个函数被调用,传入以下三个参数:比ES5,属性描述说明符将是未定义的。”如果方法装饰器返回一个值,它将被用作方法的属性描述符。举个栗子://定义装饰器函数testDecorator(target:any,key:string):void{console.log("Target:",target);console.log("key:",key);}functionlogError(errorMessage:string){returnfunction(target:any,key:string,desc:PropertyDescriptor){constmethod=desc.value;desc.value=function(){try{method();}catch(err){console.log(errorMessage);}}}}//使用装饰器类Boat{color:string="yellow";@testDecoratorgetformattedColor():string{return`thisboatcoloris${this.color}`;}@logError("Oopsboatwassunkinocean")pilot():void{thrownewError()console.log("swish");}}//实例化constboat=newBoat();boat.pilot();运行得到:Target:{}key:formattedColorOopsboatwassunkinocean2.3attributedecoratorattributedecorationattributedecorator只能用来监控类中是否声明了某个名称的属性,在属性声明之前声明。属性装饰器表达式在运行时会作为函数调用,传入两个参数:target:要装饰的类key:要装饰的类的属性名注意:属性描述符不作为参数传递给属性装饰器。因为目前没有办法在定义原型对象时描述实例属性,也没有办法建议监控或修改属性的初始化方法。//定义装饰器函数testDecorator(target:any,key:string):void{console.log("Target:",target);console.log("key:",key);}functionlogError(errorMessage:string){返回函数(目标:任意,键:字符串,desc:PropertyDescriptor){constmethod=desc.value;desc.value=function(){try{method();}catch(err){console.log(errorMessage);}}}}//使用装饰器类Boat{@testDecoratorcolor:string="yellow";//@testDecoratorgetformattedColor():string{return`thisboatcoloris${this.color}`;}@logError("Oopsboatwassunkinocean")pilot():void{thrownewError()console.log("swish");}}运行结果:Target:{}key:color2.4参数装饰器参数装饰器用于类构造函数或方法声明。接收三个参数:target:要装饰的类key:方法名index:方法中的参数索引值//定义装饰器函数testDecorator(target:any,key:string):void{console.log("Target:",target);console.log("key:",key);}functionlogError(errorMessage:string){returnfunction(target:any,key:string,desc:PropertyDescriptor){constmethod=desc.value;desc.value=function(){try{method();}catch(err){console.log(errorMessage);}}}}//参数装饰器functionparameterDecorator(target:any,key:string,index:number){console.log(key,index);}//使用装饰器类Boat{@testDecoratorcolor:string="yellow";//@testDecoratorgetformattedColor():string{return`thisboatcoloris${this.color}`;}@logError("Oopsboatwassunkinocean")pilot():void{thrownewError()console.log("swish");}fast(@parameterDecoratorspeed:string,@parameterDecoratorgenerateWake:boolean):void{if(speed==="fast"){console.log("swish");}else{console.log("nothing");}}}运行结果:Target:{}key:colorfast1fast0SummaryWe看到装饰器非常方便根据其装饰的对象不同,装饰器分为:类装饰器、属性装饰器、方法装饰器、参数装饰器。