美文网首页
10.装饰器

10.装饰器

作者: 我只会吃饭 | 来源:发表于2020-02-20 13:52 被阅读0次
    装饰器:

    装饰器是一种特殊类型的声明,它可以被附加到类声明, 方法、属性或参数上,可以修改类的行为
    简单的说 装饰器是一个方法,可以注入一些特殊的功能到类、方法、属性参数上

    装饰器的写法: 普通装饰器(不可参数)、和装饰器工厂(可传参)
    常见装饰器:类装饰器、属性装饰器、方法装饰器、参数装饰器

    类装饰器

    用于类构造函数,可以动态修改、替换、监视类的定义,在类声明之前定义(紧靠类声明)

    方式一: 普通装饰器
    function decorator(tar:any) {
        console.log(tar); 
        tar.prototype.aname = 'animal';
        tar.prototype.eat = function () { // 动态注入的方法
            console.log('啥都吃')
        }
    }
    
    @decorator
    class Animal {
        aname:string|undefined;
    }
    
    
    let animal:any = new Animal(); // 如果新增某个属性或者方法,需要将实例指定为any
    console.log(animal.aname);
    animal.eat();
    
    方式二:装饰器工厂
    function decoFactory(params:string) {
    
        return function (tar:any) {
    
            tar.prototype.aname = params;
            tar.prototype.eat =  function () {
                console.log(`${this.aname}喜欢吃盼盼法式小面包`);
            }
        }
    }
    
    @decoFactory('可乐')
    class Dog  {}
    
    let kele:any = new Dog();
    kele.eat();
    
    类装饰器-重载构造函数

    类装饰器表达式会在运行时当作函数被调用,类的构造函数作为其唯一的参数;
    类装饰器返回一个值,它会使用提供的构造函数来替换类的声明;

    function overLoad(tar:any) {
    
        return class extends tar {
            aname = '火锅';
            eat() {
                console.log(this.aname + '喜欢吃盼盼');
            }
        }
    }
    
    @overLoad // 方法和属性都需要映射(必写)
    class Dog {
        aname:string;
        constructor () {
            this.aname = '可乐'
        }
    
        eat() {
            console.log(this.aname + '喜欢吃狗粮');
        }
        
    }
    
    let hg = new Dog();
    hg.eat();
    
    属性装饰器

    属性装饰器会在运行时当做函数被调用,传入两个参数
    1. 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
    2. 属性名

    function propDecorator(params:string) {
        return function (target:any, prop:string) {
            console.log(target, 'target'); // 原型
            console.log(prop, 'props'); // 属性的名字
            target[prop] = params;
        }
    }
    
    class Person {
        @propDecorator('我是属性装饰器')
        fname:string|undefined
    }
    
    let person = new Person();
    console.log(person.fname)
    
    方法装饰器

    用于方法的属性描述符上,可以监视修改替换方法的定义
    方法修饰器接收三个参数: 原型对象、方法名字、方法的属性描述符

    function methodDecorator(params:any) {
        return function (target:any, methodName:any, desc:any) {
            console.log(target);
            console.log(methodName);
            console.log(desc);
    
            // 原型对象添加属性
            target.fname = 'fname';
            // 原型对象添加方法
            target.eat = function () {
                console.log('我只会吃饭');
            }
    
            // 修改装饰器的方法
            let valFn = desc.value; // 为run 函数
            
            // 重新赋值
            desc.value = function (...argu:any[]) {
    
                // 重新指向原函数,且修改参数
                valFn.apply(this, argu.map(v => Number(v)));
            }
            
        }
    }
    
    
    class Person {
        @methodDecorator('a')
        // 方法装饰器,写在方法的前面
        run(...argus:any[]) {
            console.log(argus);
        }
    }
    
    
    let person = new Person();
    console.log(person);
    person.run(1, 2, 3, '4');
    
    方法参数装饰器

    可以添加一些数据

    function paramsDecorator(params:string) {
        return function (target:any, methodName:string, paramsIndex: number) {
                console.log(params) ; // params
                console.log(target); // 原型对象
                console.log(methodName); // 方法名
                console.log(paramsIndex); // 参数下标
    
                target.fname = 'fname'; // 添加数据
        }
    }
    
    class Person {
        say(@paramsDecorator('我是参数') name:string) {
    
        }
    }
    
    let person = new Person();
    

    相关文章

      网友评论

          本文标题:10.装饰器

          本文链接:https://www.haomeiwen.com/subject/hcxbfhtx.html