TypeScript 基础学习(六)


今天接着学习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基础就学习完了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值