装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用 @expression
这种形式,expression
求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。
在TypeScript
中装饰器还属于实验性语法,所以要想使用必须在配置文件中tsconfig.json
编译选项中开启:
1 { 2 "compilerOptions": { 3 "experimentalDecorators": true, 4 "emitDecoratorMetadata": true, 5 } 6 }
类装饰器在类声明之前被声明(紧靠着类声明)。 类装饰器应用于类构造函数,可以用来监视,修改或替换类定义。
1 function TestDectorator(constructor:any){ 2 constructor.prototype.getName=function(){ 3 console.log('小白') 4 } 5 } 6 @TestDectorator 7 class Test{ 8 } 9 const test=new Test(); 10 (test as any).getName()//小白
通过不同参数参数返回不同数据
1 function TestDectorator(flag:boolean){ 2 if(flag){ 3 return function(constructor:any){ 4 constructor.prototype.getName=()=>{ 5 console.log('小白') 6 } 7 } 8 }else{ 9 return function(constructor:any){ 10 constructor.prototype.getName=()=>{ 11 constructor.log('小黑') 12 } 13 } 14 } 15 } 16 @TestDectorator(true) 17 class Test{ 18 } 19 const test=new Test(); 20 (test as any).getName()//小白
重构
1 function TestDectorator(){ 2 return function<T extends new (...args:any[])=>any> (constructor:T){ 3 return class extends constructor{ 4 name='小白' 5 getName(){ 6 return this.name 7 } 8 } 9 } 10 } 11 const Test=TestDectorator()(class { 12 name:string; 13 constructor(name:string){ 14 this.name=name 15 } 16 }) 17 const test=new Test('小黑') 18 console.log(test.getName())//小白
方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。 它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义
1 function getNameDectorator(target:any,protertyKey:string,descriptor: PropertyDescriptor){ 2 console.log(target,1,protertyKey,2,descriptor) 3 descriptor.value=function(){ 4 return '小白' 5 } 6 } 7 class Test{ 8 name:string; 9 constructor(name:string){ 10 this.name=name 11 } 12 @getNameDectorator 13 getName(){ 14 return this.name 15 } 16 } 17 const test=new Test('小黑') 18 console.log(test.getName())//小白
访问器装饰器声明在一个访问器的声明之前(紧靠着访问器声明)。 访问器装饰器应用于访问器的 属性描述符并且可以用来监视,修改或替换一个访问器的定义。
1 function TestDectorator(target:any,protertyKey:string,descriptor: PropertyDescriptor){ 2 // descriptor.writable = false; 3 } 4 class Test{ 5 private _name:string; 6 constructor(name:string){ 7 this._name=name 8 } 9 get name(){ 10 return this._name 11 } 12 @TestDectorator 13 set name(name:string){ 14 this._name=name 15 } 16 } 17 const test=new Test('小白') 18 test.name='小黑' 19 console.log(test.name)//小黑
属性装饰器声明在一个属性声明之前(紧靠着属性声明)
1 function nameDectorator(target: any, propertyKey: string):any{ 2 const descriptor: PropertyDescriptor = { 3 writable: false//不可修改 4 }; 5 return descriptor 6 } 7 class Test{ 8 @nameDectorator 9 name='小白' 10 } 11 const test=new Test() 12 test.name='小黑'//上面设置不能修改后,编译会报错 13 console.log()
参数装饰器声明在一个参数声明之前(紧靠着参数声明)。 参数装饰器应用于类构造函数或方法声明。
1 function TestDecorator(target: any, method: string, paramIndex: number) { 2 console.log(target, method, paramIndex); 3 // 原型,方法名,参数所在的位置 4 } 5 6 class Test { 7 getInfo(name: string, @TestDecorator age: number) { 8 console.log(name, age); 9 } 10 } 11 12 const test = new Test(); 13 test.getInfo('小白', 18);
一个实例
1 const userInfo:any=undefined 2 function TestDecorator(mes:string){ 3 return function (target:any,protertyKey:string,descriptor: PropertyDescriptor){ 4 const fn=descriptor.value//把函数保存起来 5 descriptor.value=function(){ 6 try{ 7 fn() 8 }catch{ 9 console.log(mes) 10 } 11 } 12 } 13 } 14 15 class Test{ 16 @TestDecorator('userInfo.name找不到') 17 getName(){ 18 return userInfo.name 19 } 20 @TestDecorator('userInfo.age找不到') 21 getAge(){ 22 return userInfo.age 23 } 24 } 25 const test=new Test() 26 test.getName()//userInfo.name找不到 27 test.getAge()//userInfo.age找不到