引读:为何要写装饰器这篇文章了,装饰器给人感受很NB的样子,不少同窗对装饰器的用法仍是很模糊,文档又让他们很难彻底理解;但愿读了这篇博客之后,能对装饰器有不同的理解;api
// 类装饰器:普通装饰器(没法传参) function logClass(params){ // params 就是当前类 console.log(params) params.prototype.apiUrl = "动态扩展的属性" params.prototype.fetch = function(){ console.log('我是一个fetch方法') } } @logClass class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // 动态扩展的属性 http.fetch() // 我是一个fetch方法
// 类装饰器:装饰器工厂(能够传参) function logClass(params){ console.log(params) // params调用时的实参 return function(target){ // target 当前类 HttpClient console.log(target) params.prototype.apiUrl = params } } @logClass('newbanker') class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // newbanker
// 装饰器能够修改当前类的构造函数和方法 // 类装饰器表达式会在运行时当作函数被调用,类的构造函数做为其惟一参数 // 若是类装饰器返回一个值,它会使用提供的构造函数来替换类的声明 // 下面是一个函数重载的例子 function logClass(params){ console.log(params) // params调用时的实参 return class extends target { apiUrl = "我是修改后的数据" getData(){ console.log(this.apiUrl+'------') } } } @logClass class HttpClient { constructor(){ this.apiUrl = "我是构造函数里面的apiUrl" }
// 类装饰器:普通装饰器(没法传参) function logClass(params){ // params 就是当前类 console.log(params) params.prototype.apiUrl = "动态扩展的属性" params.prototype.fetch = function(){ console.log('我是一个fetch方法') } } @logClass class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // 动态扩展的属性 http.fetch() // 我是一个fetch方法
// 类装饰器:装饰器工厂(能够传参) function logClass(params){ console.log(params) // params调用时的实参 return function(target){ // target 当前类 HttpClient console.log(target) params.prototype.apiUrl = params } } @logClass('newbanker') class HttpClient { constructor(){ } getData(){ } } let http = new HttpClient() console.log(http.apiUrl) // newbanker
// 装饰器能够修改当前类的构造函数和方法 // 类装饰器表达式会在运行时当作函数被调用,类的构造函数做为其惟一参数 // 若是类装饰器返回一个值,它会使用提供的构造函数来替换类的声明 // 下面是一个函数重载的例子 function logClass(params){ console.log(params) // params调用时的实参 return class extends target { apiUrl = "我是修改后的数据" getData(){ console.log(this.apiUrl+'------') } } } @logClass class HttpClient { constructor(){ this.apiUrl = "我是构造函数里面的apiUrl" } getData(){ console.log(this.apiUrl) } } let http = new HttpClient() console.log(http.apiUrl) // 我是修改后的数据
// 类装饰器:装饰器工厂(能够传参) function logClass(params){ console.log(params) // params调用时的实参 return function(target){ // target 当前类 HttpClient console.log(target) } } // 属性装饰器 function logProperty(params){ return function(target, attr){ console.log(target) // console.log(attr) // 当前属性url target.attr = params } } @logClass class HttpClient { @logProperty('https://baidu.com') public url getData(){ } }
// 方法装饰器 function logMethod(params){ return function(target, methodName, desc){ console.log(target) // 原型对象,能够扩展类的原型属性和方法; // 能够扩展当前实例的属性和方法 target.apiUrl = "http://www.sina.cn" target.run = function(){ console.log('run') } console.log(methodName) // 当前方法名 getData // 修改装饰器的方法,把装饰器方法里面传入的全部参数改成string类型; // 保存当前方法 let save = desc.value desc.value = function(...args){ args.map((v) => { return String(v) }) console.log(v) } console.log(desc) // 描述信息 { value: f, xxx: xxx } // 不加此方法会直接替换实例的方法,加上会修改 save.apply(this, args) // 把当前方法this传进去,表明在这个方法里面调用save方法;并传入参数; } } class HttpClient { public url: any | undefind; constructor(){ } @get('http://www.baidu.com') getData(args){ console.log(args) // ['123', 'string'] console.log('我是getData的method') } } let http = new HttpClient(); console.log(http.apiUrl) // http://www.sina.cn http.getData(123, 'string')
// 方法参数装饰器 function logParams(params){ return function(target, paramsName, paramsIndex){ console.log(params) // xxxx console.log(target) // console.log(paramsName) // getData console.log(paramsIndex) // 0 } } class HttpClient { getData(@logParams1('xxxx') uuid: any, @logParams2('xxxx') name: any){ console.log(uuid) // 123 } } let http: any = new HttpClient(); http.getData(123)
@logClass1('http:www.baidu.con') @logClass2('xxxx') class HttpClient { @logAttribute() public apiUrl: string | undefind constructor(){ } @logMethod() getData(){ } setData(@logParams1() attr1: any, @logParams2() attr2: any){ } } let http: any = new HttpClient(); // 属性装饰器 > 方法装饰器 > 方法参数装饰器2 > 方法参数装饰器1 > 类装饰器2 > 类装饰器1