TypeScript 个人笔记(三)

·  阅读 37
TypeScript 个人笔记(三)

类的定义

在 TypeScript 中,我们可以通过 Class 关键字来定义一个类

class Person {
    name!: string;
    constructor(_name: string) {
        this.name = _name
    }
    getName(): void {
        console.log(this.name);
    }
}
let p = new Person('如花')
p.getName()
复制代码

我们也可以把属性定义直接写到构造函数的参数里面去

 class People {
     constructor(public name: string) { }
     getName(): void {
         console.log(this.name);

     }
 }
 let p1 = new Person('石榴姐')
 p1.getName()
复制代码

当我们定义一个类的时候,会得到 2 个类型
一个是构造函数类型的函数类型(当做普通构造函数的类型)另一个是类的实例类型(代表实例)

 class Component {
     static myName: string = "静态名称属性";
     myName: string = "实例名称属性";
 }
 //ts 一个类型 一个叫值
 //放在=后面的是值
 let com = Component; //这里是代表构造函数
//冒号后面的是类型
let k: Component = new Component(); //这里是代表实例类型
let f: typeof Component = com
复制代码

存取器

在 TypeScript 中,我们可以通过存取器来改变一个类中属性的读取和赋值行为

 class Admin {
     userName: string
     constructor(userName: string) {
         this.userName = userName

     }
     get name() {
         return this.userName
     }
     set name(value) {
         this.userName = value
     }
 }
 let user = new Admin('祝枝山')
 user.name = '唐伯虎'
 console.log(user.name);
复制代码

其实我们可以看看翻译成 es5 的代码
原理很简单 就是使用了 Object.defineProperty 在类的原型上面拦截了属性对应的 get 和 set 方法

 var Admin = /** @class */ (function () {
     function Admin(userName) {
         this.userName = userName;
     }
     Object.defineProperty(Admin.prototype, "name", {
         get: function () {
             return this.userName;
         },
         set: function (value) {
             this.userName = value;
         },
         enumerable: false,
         configurable: true
     });
     return Admin;
 }());
 var user = new Admin('祝枝山');
 user.name = '唐伯虎';
 console.log(user.name);
复制代码

readonly 只读属性

readonly 修饰的变量只能在构造函数中初始化
TypeScript 的类型系统同样也允许将 interface、type、 class 上的属性标识为 readonly
readonly 实际上只是在编译阶段进行代码检查。

 class Fruit {
     public readonly  name:string
     constructor(name:string){
         this.name = name

     }
     eatFruit(name:string){
         this.name = name // error Cannot assign to 'name' because it is a read-only property.

     }
 }
 let apple = new Fruit('苹果')
复制代码

继承

子类继承父类后子类的实例就拥有了父类中的属性和方法,可以增强代码的可复用性 将子类公用的方法抽象出来放在父类中,自己的特殊逻辑放在子类中重写父类的逻辑
super 可以调用父类上的方法和属性
在 TypeScript 中,我们可以通过 extends 关键字来实现继承


class Fruit {
    fruitName: string //定义实例的属性,默认省略public修饰符
    constructor(fruitName: string) {
        this.fruitName = fruitName
    }
    getName(): string {
        return this.fruitName
    }
    setName(value: string) {
        this.fruitName = value
    }
}
class Apple extends Fruit {
    size: number
    constructor(fruitName: string, size: number) {
        super(fruitName); //继承父亲的属性
        this.size = size
    }
    getSize(): number {
        return this.size
    }

}
let a1 = new Apple('苹果', 9)
console.log(a1);
复制代码

类里面的修饰符

public 类里面 子类 其它任何地方外边都可以访问
protected 类里面 子类 都可以访问,其它任何地方不能访问
private 类里面可以访问,子类和其它任何地方都不可以访问

class Dog {
   public name: string 
   private age:number
   protected bark:string
    constructor(name: string,age:number, bark:string) {
        this.name = name
        this.age = age
        this.bark = bark
    }
    getName(): string {
        return this.name
    }
    setName(value: string) {
        this.name = value
    }
}
class Husky extends Dog {
    size: string
    constructor(name: string, age:number,bark:string,size: string) {
        super(name,age,bark); //继承父亲的属性
        this.size = size
    }
    getSize(): string {
        return this.size
    }

}
let dog1 = new Husky('哈士奇', 12,'嗷嗷 嗷~~',"50kg")
console.log(dog1.name);
// console.log(dog1.age); // Property 'brak' does not exist on type 'Husky'.
// console.log(dog1.brak);// Property 'brak' does not exist on type 'Husky'.

复制代码

静态属性 静态方法

类的静态属性和方法是直接定义在类本身上面的 所以也只能通过直接调用类的方法和属性来访问

class Parent {
    static mainName = "Parent";
    static getmainName() {
      console.log(this); //注意静态方法里面的this指向的是类本身 而不是类的实例 
                         //对象 所以静态方法里面只能访问类的静态属性和方法
      return this.mainName;
    }
    public name: string;
    constructor(name: string) {
      //构造函数
      this.name = name;
    }
  }
  console.log(Parent.mainName);
  console.log(Parent.getmainName());
复制代码

抽象类和抽象方法

抽象类,无法被实例化,只能被继承并且无法创建抽象类的实例
子类可以对抽象类进行不同的实现
抽象方法只能出现在抽象类中并且抽象方法不能在抽象类中被具体实现,只能在抽象类的子类中实现(必须要实现)
使用场景:
我们一般用抽象类和抽象方法抽离出事物的共性 以后所有继承的子类必须按照规范去实现自己的具体逻辑 这样可以增加代码的可维护性和复用性
使用 abstract 关键字来定义抽象类和抽象方法

abstract class Animal1 {
  name!: string;
  abstract speak(): void;
}
class Cat extends Animal {
  speak() {
    console.log("喵喵喵");
  }
}
let animal = new Animal1(); //直接报错 无法创建抽象类的实例
let cat = new Cat();
cat.speak();
复制代码

重写(override)和重载(overload)的区别

重写是指子类重写继承自父类中的方法
重载是指为同一个函数提供多个类型定义

class Animal {
  speak(word: string): string {
    return "动物:" + word;
  }
}
class Dog extends Animal {
  speak(word: string): string {
    return "狗:" + word;
  }
}
let cat = new Dog();
console.log(Dog.speak("汪汪~"));
复制代码

上面是重写

下面是重载

function double(val: number): number;
function double(val: string): string;
function double(val: any): any {
  if (typeof val == "number") {
    return val * 2;
  }
  return val + val;
}

let r = double(1);
console.log(r);

复制代码
分类:
前端
分类:
前端
收藏成功!
已添加到「」, 点击更改