• 深入Typescript03Typescript中的类(努力加餐饭)


    Typescript中的类

    一.TS中定义类

    class Pointer{
        x!:number; // 实例上的属性必须先声明
        y!:number;
        constructor(x:number,y?:number,...args:number[]){
            this.x = x;
            this.y = y as number;
        }
    }
    let p = new Pointer(100,200);
    
    • 实例上的属性需要先声明在使用,构造函数中的参数可以使用可选参数和剩余参数

    二.类中的修饰符

    • public修饰符(谁都可以访问到)
    class Animal {
        public name!: string; // 不写public默认也是公开的
        public age!: number;
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
    }
    class Cat extends Animal {
        constructor(name: string, age: number) {
            super(name, age);
            console.log(this.name,this.age); // 子类访问
        }
    }
    let p = new Cat('Tom', 18);
    console.log(p.name,p.age); // 外层访问
    class Animal {
        constructor(public name: string, public age: number) {
            this.name = name;
            this.age = age;
        }
    }
    
    • 我们可以通过参数属性来简化父类中的代码

    • protected修饰符 (自己和子类可以访问到)

    class Animal {
        constructor(protected name: string, protected age: number) {
            this.name = name;
            this.age = age;
        }
    }
    class Cat extends Animal {
        constructor(name: string, age: number) {
            super(name, age);
            console.log(this.name, this.age)
        }
    }
    let p = new Cat('Tom', 18);
    console.log(p.name,p.age);// 无法访问
    
    • private修饰符 (除了自己都访问不到)
    class Animal {
        constructor(private name: string, private age: number) {
            this.name = name;
            this.age = age;
        }
    }
    class Cat extends Animal {
        constructor(name: string, age: number) {
            super(name, age);
            console.log(this.name, this.age); // 无法访问
        }
    }
    let p = new Cat('Tom', 18); 
    console.log(p.name,p.age);// 无法访问
    
    • readonly修饰符 (仅读修饰符)
    class Animal {
        constructor(public readonly name: string, public age: number) {
            this.name = name;
            this.age = age;
        }
        changeName(name:string){
            this.name = name; // 仅读属性只能在constructor中被赋值
        }
    }
    class Cat extends Animal {
        constructor(name: string, age: number) {
            super(name, age);
        }
    }
    let p = new Cat('Tom', 18); 
    p.changeName('Jerry');
    
    


    三.静态属性和方法

    class Animal {
        static type = '哺乳动物'; // 静态属性
        static getName() { // 静态方法
            return '动物类';
        }
        private _name: string = 'Tom';
    
        get name() { // 属性访问器
            return this._name;
        }
        set name(name: string) {
            this._name = name;
        }
    }
    let animal = new Animal();
    console.log(animal.name);
    
    • 静态属性和静态方法是可以被子类所继承的

    四.Super属性

    class Animal {
        say(message:string){
            console.log(message);
        } 
        static getType(){
            return '动物'
        }
    }
    class Cat extends Animal {
        say(){ // 原型方法中的super指代的是父类的原型
            super.say('猫猫叫');
        }
        static getType(){ // 静态方法中的super指代的是父类
            return super.getType()
        }
    }
    let cat = new Cat();
    console.log(Cat.getType())
    

    五.类的装饰器

    • 简单来说,就是给一个类,添加一些好用的方法,其他类也能用,写到原型上面,参考5.1
    • 或者是修饰类里的一些属性方法,搞通用的那种函数,用来修饰,节省代码,可参考5.2,5.3
    • 还可以修饰函数的参数哇 5.4
    • 装饰器作用就是为了扩展类,扩展类中的属性和方法
    • 只能修饰类,不可以修饰函数,函数有变量提升的问题
    • 装饰器必须是一个函数
    • 执行=洋葱模型,先从外层执行,执行完后,从内层倒序执行,一层一层剥开,再一层一层执行


    1.装饰类

    function addSay(target:any){
        target.prototype.say = function(){console.log('say')}
    }
    @addSay
    class Person {
        say!:Function
    }
    let person = new Person
    person.say();
    
    • 装饰类可以给类扩展功能,需要开启experimentalDecorators:true

    2.装饰类中属性

    // target  是类的原型,,key 是需要修饰的属性
    function toUpperCase(target:any,key:string){
        let value = target[key]; 
        Object.defineProperty(target,key,{ // 原型定义属性
            get(){
                return value.toUpperCase();
            },
            set(newValue){
                value = newValue
            }
        })
    }
    function double(target: any, key: string) {
        let value = target[key];
        Object.defineProperty(target, key, {
            get() {
                return value * 2;
            },
            set(newValue) {value = newValue}
        })
    }
    class Person {
        @toUpperCase
        name: string = 'JiangWen'
    	@double
        static age: number = 10;
        getName() {
            return this.name;
        }
    }
    let person = new Person();
    console.log(person.getName(),Person.age)
    
    • 装饰属性可以对属性的内容进行改写,装饰的是实例属性则target指向类的原型、装饰的是静态属性则target执行类本身~

    3.装饰类中方法

    // 设置某些方法属性是否可用
    function noEnum(target:any,key:string,descriptor:PropertyDescriptor){
        console.log(descriptor)
        descriptor.enumerable = false;
    }
    class Person {
        @toUpperCase
        name: string = 'JiangWen'
        @double
        static age: number = 10;
        @noEnum
        getName() {
            return this.name;
        }
    }
    let person = new Person();
    console.log(person); // getName 不可枚举
    

    4.装饰参数

    function addPrefix(target:any,key:string,paramIndex:number){
        console.log(target,key,paramIndex); // Person.prototype getName  0 
    }
    class Person {
        @toUpperCase
        name: string = 'JiangWen'
        @double
        static age: number = 10;
        prefix!:string
        @noEnum
        getName(@addPrefix prefix:string) {
            return this.name;
        }
    }
    

    六.抽象类

    • 抽象类无法被实例化,只能被继承,抽象方法不能在抽象类中实现,只能在抽象类的具体子类中实现,而且必须实现。
    • 定义类型时void表示函数的返回值为空
    abstract class Animal{
        name!:string;
        abstract speak():void
    }
    class Cat extends Animal {
        speak(){
            console.log('猫猫叫');
        }
    }
    class Dog extends Animal{
        speak():string{
            console.log('汪汪叫');
            return 'wangwang'
        }
    }
    
  • 相关阅读:
    如何修改mysql root密码
    【STL】list基础(转)
    时间控制timer settimeout setinterval
    刷新ArrayCollection的显示控件
    需要科普的网站
    flex 拖拽数据
    常用的资源网站
    as3 性能优化
    对象池
    Bitmap与Bitmapdata
  • 原文地址:https://www.cnblogs.com/sugartang/p/16220177.html
Copyright © 2020-2023  润新知