传统的面向对象语言基本都是基于类的,JavaScript基于原型的方式让开发者多了很多理解成本,在es6以后,JavaScript拥有了class关键字,虽然本质依然是构造函数,但是开发者已经可以比较舒服的使用class了。
JavaScript的class依然有一些特性没有加入,比如修饰符和抽象类等。

抽象类

抽象类作为其他派生类的基类使用,它们一般不会直接被实例化,不同于接口,抽象类可以包含成员的实现细节。
abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法。
比如创建一个Animal抽象类:

  1. abstract class Animal {
  2. abstract makeSound():void;
  3. move():void{
  4. console.log('roaming the earth...')
  5. }
  6. }

若是实例化此抽象类会报错:
类 - 图1
我们不能直接实例化抽象类,通常需要我们创建子类继承基类,然后实例化子类。

  1. class Cat extends Animal {
  2. makeSound () {
  3. console.log("miao miao");
  4. }
  5. }
  6. const cat = new Cat()
  7. cat.makeSound() // miao miao
  8. cat.move() // roaming the earch...

访问限定符

传统面向对象语言通常都有访问限定符,ts中有三类访问限定符,分别是:public、private、protected。

public

在typescript的类中,成员都默认为public,被此限定符修饰的成员是可以外部访问。

  1. class Car {
  2. public run() {
  3. console.log('启动。。。')
  4. }
  5. }
  6. const car = new Car()
  7. car.run() // 启动。。。

private

当成员被设置为private之后,被此限定符修饰的成员只可以被类的内部访问。
类 - 图2

protected

当成员被设置为protected之后,被此限定符修饰的成员是只可以被类的内部以及类的子类访问。

  1. class Car {
  2. protected run() {
  3. console.log('启动...')
  4. }
  5. }
  6. class GTR extends Car {
  7. init() {
  8. this.run();
  9. }
  10. }
  11. const car = new Car()
  12. const gtr = new GTR()
  13. car.run() //[ts]属性“run”受保护,只能在类“Car”及其子类中访问。
  14. gtr.init()// 启动...
  15. gtr.run() // [ts]属性“run”受保护,只能在类“Car”及其子类中访问。

class可以作为接口

类(class)也可作为接口。
把class作为interface使用,在react工程中是很常用的。
比如这个轮播组件rc-carousel

  1. export default class Carousel extends React.Component<Props,State>{}

由于组件需要传入props的类型Props,同时,有需要设置默认props即defaultProps。
此时即体现了class作为接口的优势。
我们先声明一个类,这个类包含组件props所需的类型和初始值:

  1. //props的类型
  2. export default class Props {
  3. public children: Array<React.ReactElement<any>> | React.ReactElement<any> | never[] = []
  4. public speed:number = 500
  5. public height: number = 160
  6. public animation: string = 'easeInputOutQuad'
  7. public isAuto: boolean = true
  8. public autoPlaInterval: number = 4500
  9. public afterChange: () => {}
  10. public beforeChange: () => {}
  11. public selesctedColor: () => {}
  12. public selesctedColor: string
  13. public showDots: boolean = true
  14. }

当我们需要传入props类型的时候直接将Props作为接口传入,此时Props的作用就是接口,而当需要我们设置defaultProps初始值时,我们只需要:

  1. public static defaultProps = new Props()

Props 的实例就是defaultProps的初始值,这就是class作为接口的实际应用,我们用一个class起到了接口和设置初始值两个作用,方便统一管理,减少了代码量。