typescript - 9.装饰器
装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为。
通俗的讲装饰器就是一个方法,可以注入到类、方法、属性参数上来扩展类、属性、方法、参数的功能。
常见的装饰器有:
- 类装饰器
- 属性装饰器
- 方法装饰器
- 参数装饰器
装饰器的写法:
- 普通装饰器(无法传参)
- 装饰器工厂(可传参)
装饰器是过去几年中js最大的成就之一,已是Es7的标准特性之一
类装饰器
普通装饰器(无法传参)
function logClass(params:any){
console.log(params);
// params 就是当前类
params.prototype.apiUrl='动态扩展的属性';
params.prototype.run=function(){
console.log('我是一个run方法');
}
}
@logClass
class HttpClient{
constructor(){
}
getData(){
}
}
var http:any=new HttpClient();
console.log(http.apiUrl); //动态扩展的属性
http.run(); //我是一个run方法
装饰器工厂(可传参)
function logClass(params:string){
return function(target:any){
console.log(target); //当前类:HttpClient
console.log(params); //http://www.itying.com/api
target.prototype.apiUrl=params;
}
}
@logClass('http://www.itying.com/api')
class HttpClient{
constructor(){
}
getData(){
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
属性装饰器
属性装饰器表达式会在运行时当作函数被调用,传入下列2个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、成员的名字。
//类装饰器
function logClass(params:string){
return function(target:any){
// console.log(target);
// console.log(params);
}
}
//属性装饰器
function logProperty(params: any) {
return function (target: any, attr: any) {
console.log(target);
console.log(attr);
target[attr] = params;
}
}
@logClass('xxxx')
class HttpClient {
@logProperty('监视属性')
public url: any | undefined;
constructor() {
}
getData() {
console.log(this.url);
}
}
var http = new HttpClient();
http.getData();
方法装饰器
它会被应用到方法的 属性描述符上,可以用来监视,修改或者替换方法定义。
方法装饰会在运行时传入下列3个参数:
1、对于静态成员来说是类的构造函数,对于实例成员是类的原型对象。
2、成员的名字。
3、成员的属性描述符。
扩展方法
正常的扩展方法.
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(`0.params${params}`);
console.log(`1.target:`);
console.log(target);
console.log("2.methodName:");
console.log(methodName);
console.log("3.desc:");
console.log(desc);
target.Apiurl='xxxx';
target.run=function(){
console.log('5.run');
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('param参数在这里~~~')
getData(){
console.log("6.this.url");
console.log(this.url);
}
}
var http:any=new HttpClient();
console.log("4.http.Apiurl");
console.log(http.Apiurl);
http.run();
http.getData();
修改方法内容
function get(params:any){
return function(target:any,methodName:any,desc:any){
// console.log(`0.params${params}`);
// console.log(`1.target:`);
// console.log(target);
// console.log("2.methodName:");
// console.log(methodName);
// console.log("3.desc:");
// console.log(desc);
//修改装饰器的方法 把装饰器方法里面传入的所有参数改为string类型
let oMethod = desc.value;
desc.value = function name(...args:any[]) {
args = args.map(value=>{
return String(value);
})
oMethod.apply(this,args);
console.log(args);
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('param参数在这里~~~')
getData(){
console.log("这里是getData方法内~");
}
}
var http:any=new HttpClient();
http.getData(123,"aabb");