今天接着学习ts中的类相关知识
Ts中的装饰器
装饰器的定义
/*
装饰器:装饰器是一种特殊类型的声明,他能够被附加到类声明,方法,属性或参数上,可以修改类的行为,
通俗的来说 装饰器就是一个方法,可以注入到类,方法,属性参数上来扩展类属性方法参数的功能。
常见的装饰器有:类装饰器,属性装饰器,方法装饰器,方法参数装饰器
装饰器的写法: 普通装饰器(无法传参) , 装饰器工厂(可传参)
装饰器是过去技能中js最大的成就之一,es7的标准特性之一
*/
类装饰器
//1.类装饰器:类装饰器在类声明之前被声明(紧靠着类声明),类装饰器应用于类构造函数,可以用来见识,修改或者替换类定义,传一个参数
function logClass(params:any){
console.log(params)
//params 就是当前类
params.prototype.apiUrl = '动态扩展的属性'//这就相当于给类扩展了一个属性
params.prototype.run = function(){
console.log('我是扩展的run方法')
}
}
@logClass//这里就相当于默认传入了当前类
class HttpClient{//如果报错,修改tsconfig.json中的"experimentalDecorators": true, 即可
constructor(){}
getData(){}
}
var http:any = new HttpClient();
console.log(http.apiUrl)
http.run()
属性装饰器
//3.属性装饰器
//属性装饰器表达式会在运行时当做函数被调用,传入2个参数
// 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
// 成员的名字
function logClass(params: string) {//类装饰器
return function (target: any) {
console.log(target, params)
target.prototype.apiUrl = `www.${params}.com`
}
}
function logProperty(params: any) {
return function (target: any, attr: any) {
console.log(target, attr)
target[attr] = params
}
}
@logClass('类装饰器')
class HttpClient {
@logProperty('属性装饰器')
public url: any | undefined;
constructor() { }
getData() {
console.log(this.url)
}
}
var http: any = new HttpClient()
http.getData()
装饰器工厂
// 类装饰器:装饰器工厂(可传参)
function logClass(params:string){
return function(target:any){
console.log(target,params)
target.prototype.apiUrl = `www.${params}.com`
}
}
@logClass('hello')
class HttpClient{//如果报错,修改tsconfig.json中的"experimentalDecorators": true, 即可
constructor(){}
getData(){}
}
var http:any = new HttpClient()
console.log(http.apiUrl)
// 类装饰器 还可以重载构造函数
// 类装饰器表达式会在运行时当做函数被调用,类的构造函数作为其唯一的参数
// 如果类装饰器返回一个值,他会使用提供的构造函数来替换类的声明
function logClass(target:any){
console.log(target)
return class extends target{
apiUrl:any = '我是修改后的数据';
getData(){
console.log(this.apiUrl+'------')
}
}
}
@logClass
class HttpClient{
public apiUrl:string|undefined;
constructor(){
this.apiUrl = '我是构造函数里面的apiUrl'
}
getData(){
console.log(this.apiUrl)
}
}
var http = new HttpClient()
http.getData()
方法装饰器
//4.方法装饰器:它会被应用到方法的属性描述符上,可以用来监视,修改或者替换方法的定义,
// 方法装饰器会在运行时传入下列3个参数
// 对于静态城来说是类的构造函数,对于实例成员是类的原型对象
// 成员的名字
// 成员的属性描述符
//方法装饰器
function logMethod(params: any) {
return function (target: any, methodName: any, desc: any) {
console.log(target)
console.log(methodName)
console.log(desc)
target.apiUrl = 'xxxxxxxxx'
target.run = function () {
console.log('我是扩展方法')
}
}
}
class HttpClient {
public url: any | undefined;
constructor() { }
@logMethod('http://127.0.0.1')
getData() {
console.log(this.url)
}
}
var http: any = new HttpClient()
console.log(http.apiUrl)
http.run()
//通过方法装饰器 修改当前类中方法
function logMethod(params: any) {
return function (target: any, methodName: any, desc: any) {
console.log(params)
console.log(target)
console.log(methodName)
console.log(desc.value)//这就是类中的方法
// 修改装饰器的方法,把装饰器方法里面传入的参数改为string类型
// 1.保存当前方法
var old = desc.value;
// 2.重写
desc.value = function (...args: any[]) {
args = args.map(item => {
return String(item)
})
console.log(args)
old.apply(this, args)
}
}
}
class HttpClient {
public url: any | undefined;
constructor() { }
@logMethod('http://127.0.0.1')
getData() {
console.log('我是原方法')
}
}
var http: any = new HttpClient()
http.getData('123', 123, 'xxxx')
方法参数装饰器
// 方法参数装饰器
// 参数装饰器表达式会在运行时当作函数被调用,可以使用参数装饰器为类的原型增加一些元素数据,传入以下3个参数
// 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
// 方法的名字
// 参数在函数参数列表中的索引
function logParams(params: any) {
return function (target: any, methodName: any, paramsIndex: any) {
console.log(params)
console.log(target)
console.log(methodName)
console.log(paramsIndex)
target.apiUrl = params
}
}
class HttpClient {
public url: any | undefined;
constructor() { }
getData(@logParams('xxxxxxxxxx') uuid: any) {
console.log(uuid)
}
}
var http:any = new HttpClient()
http.getData(123456)
console.log(http.apiUrl)
装饰器的执行顺序
// 装饰器的执行顺序
function logClass1(params: string) {
return function (target: any) {
console.log('类装饰器1')
}
}
function logClass2(params: string) {
return function (target: any) {
console.log('类装饰器2')
}
}
function logAttr(params?: string) {
return function (target: any, attrName: any) {
console.log('属性装饰器')
}
}
function logMethod(params?: string) {
return function (target: any, attrName: any, desc: any) {
console.log('方法装饰器')
}
}
function logParams1(params?: string) {
return function (target: any, methodName: any, index: any) {
console.log('参数装饰器1')
}
}
function logParams2(params?: string) {
return function (target: any, methodName: any, index: any) {
console.log('参数装饰器2')
}
}
@logClass1('logclass1')
@logClass2('logclass2')
class HttpClient {
@logAttr('logAttr')
public apiUrl: string | undefined
constructor() { }
@logMethod()
getData() {
console.log('1')
}
setData(@logParams1() attr1: any, @logParams2() attr2: any) {
}
}
// 顺序: 属性》方法》方法参数》类
// 如果有多个同样类型的装饰器 先执行后面的
到此 ts基础就学习完了。