「TypeScript」入门进阶(二)✈️---类

698 阅读8分钟

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

🎉 前言

  • 虽然之前有学过TypeScript但是平时业务上面都还是用JavaScript来开发导致逐渐对TypeScript生疏了。
  • 借此更文活动的机会再来一起学习一下TypeScript的知识吧。
  • 在之前的文章中我们TypeScript的基础知识过了一遍,是不是发现其实也不会很难呢。
  • 本文也是TypeScript进阶篇的第二篇,关于基础篇可以看我之前分享的文章喔~
  • 本文有2400+字,阅读可能需要十分钟~ 🥂

🥛 关于类

🍸 类的由来

  • 提到类,可能大部分人都会想到JAVA,毕竟在大学也被这门面向对象的语言折磨过。
  • 在之前我们用JavaScript生成实例对象的传统方法还是通过构造函数。
function People(name,sex){
  this.name=name;
  this.sex=sex;
}
People.prototype.speak = function(){
    return "我是" + this.name+"我是"+this.sex+"的";
}
let xm=new People('小明','男')
console.log(xm.speak()) //我是小明我是男的
console.log(xm.name,xm.sex); //小明 男
  • 正如上面所示我们创建了一个函数,然后使用了new将它实例化,这样就出来了一个xm对象。
  • 可能我们习惯了这种写法也并没有觉得有什么不妥,但是对于新人来说这样就不太好理解了,所以ES6才引入了一个类(Class)的概念。

🍹 ES6中的类

🍺 类的基本使用

  • ES6引入了类(Class)的概念,通过class关键字可以定义类。
class People{//定义了一个名字为People的类
  constructor(name){//constructor是一个构造方法,用来接收参数
      this.name = name;
  }
  speak(){//这是一个类的方法
    return "我是" + this.name;
  }
}
let xm=new People('小明')
console.log(xm.speak()) //我是小明
console.log(xm.name); //小明
  • constructor方法是类的构造函数的默认方法,通过new命令生成对象实例时,自动调用该方法。
  • 在上面的例子中我们可以看到之前通过function定义方法然后要通过原型链来新增方法,现在只需要用class包起来,其中加入一个构造方法constructor来接收参数和设置参数,事实上每一个类都要有一个构造方法,这个类里面的方法speak外部也是可以直接调用的,事实上这样看起来会更加舒服简洁一点,也对新人比较友好。

🍻 类的继承

  • 接着上面的例子,我们可以跟对类进行继承,通过extends来实现。
class Student extends People{//定义了一个名字为Student的类继承了People
  constructor(name){//constructor是一个构造方法,用来接收参数
      super(name) //super调用父类的构造方法
  }
  eat(){
    console.log("我在吃饭"+"我是"+this.name)
  }
  talk(){
    console.log(super.speak())
  }
}
let xm=new Student('小红')
xm.eat() //我在吃饭我是小红
xm.talk()//我是小红
console.log(xm.name); //小红
  • 可以看到我们定义了一个Student类,这个类继承了People类,通过extends连接,我们可以使用super来使用父类的构造函数和定义的方法。

🍽️ getter和setter

  • 在类中也可以使用get set关键字,可以对某个属性设置值和取出值,可以拦截存取行为。
class People{//定义了一个名字为People的类
  constructor(name){//constructor是一个构造方法,用来接收参数
      this.name = name;
  }
  get name() {
    return '小明';
  }
  set name(value) {
    console.log('setter: '+value);
  }
}
let xm=new People('小红') //setter: 小红
xm.name="小兰"  //setter: 小兰
console.log(xm.name) //小明
  • 可以看到加上了set关键字后,我们每次给值给name都会调用一次set里面的方法。
  • 再加上了get关键字后,我们实例化xm取出的值是小明而不是小兰小红,是因为我们取值只会经过get里的方法return的都是小明

🥢 静态方法

  • 我们的类相当于是实例的原型,我们类中的所有方法都会被实例继承,那么我们可以不可以有一种场景不让我们类里面的方法被实例继承呢?我们可以通过静态方法实现。
class People{//定义了一个名字为People的类
  constructor(name){//constructor是一个构造方法,用来接收参数
      this.name = name;
  }
  static sleep(){
    console.log('我在睡觉')
  }
}
let xm=new People('小明') 
People.sleep() //我在睡觉
xm.sleep() // Uncaught TypeError: xm.sleep is not a function
  • 可以看到我们给方法加上了静态static之后实例xm就不可以使用那个方法了,但是我们的类却还是可以直接使用sleep方法。
  • 如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为静态方法

🍾 TypeScript的类

🍶 类的类型

  • 我们都知道在TypeScript中为了规范我们的数据类型,每个变量在定义的时候都要给一个类型,那么我们的类当然也是需要给类型的。
class People{//定义了一个名字为People的类
  name:string;
  constructor(name:string){//constructor是一个构造方法,用来接收参数
      this.name = name;
  };
  sleep():string{
    return '我在睡觉,我是'+this.name
  }
}
let xm:People=new People('小明')
console.log(xm.sleep()) //我在睡觉,我是小明
  • 实际上类加上类型跟接口差不多。

🍵 访问修饰符

  • TypeScript我们可以使用三种访问修饰符,分别是public private protected
    • public - 翻译过来意思是公众的 用于修饰该属性或者方法是公有的,可以在任何地方被访问,当我们不设置修饰符的时候默认所有的属性和方法都是public的。
    • private - 翻译过来意思是私有的 用于修饰该属性或者方法是私有的,不可以在它的类外部调用和访问,包括它的子类。
    • protected - 翻译过来意思是受保护的 用于修饰该属性或者方法是受保护的,不可以在它的类外部调用,但是可以在子类调用和访问
class People{//定义了一个名字为People的类
  public name:string;
  constructor(name:string){//constructor是一个构造方法,用来接收参数
      this.name = name;
  };
  public sleep():string{
    return '我在睡觉,我是'+this.name
  }
}
let xm:People=new People('小明')
console.log(xm.name) //小明
console.log(xm.sleep()) //我在睡觉,我是小明
  • 我们可以看到设置了public的属性在类的外部是可以访问的。
class People{//定义了一个名字为People的类
  public name:string;
  private sex:string="男"
  constructor(name:string){//constructor是一个构造方法,用来接收参数
      this.name = name;
  };
  public sleep():string{
    return '我在睡觉,我是'+this.sex+'的'
  }
}
let xm:People=new People('小明')
console.log(xm.sleep()) //我在睡觉,我是男的
console.log(xm.sex) //报错 属性“sex”为私有属性,只能在类“People”中访问
  • 当我们给一个属性设定了private私有的时候它在类的内部是可以访问的,可以看到sleep方法访问sex是成功的,而当我们在外部直接使用sex的时候会报 属性“sex”为私有属性,只能在类“People”中访问
class People{//定义了一个名字为People的类
  public name:string;
  protected age:number;
  constructor(name:string,age:number){//constructor是一个构造方法,用来接收参数
      this.name = name;
      this.age = age;
  };
}
class Student extends People{//定义了一个名字为Student的类继承了People
  constructor(name:string,age:number){//constructor是一个构造方法,用来接收参数
      console.log(super(name,age))//super调用父类的构造方法
  }
}
let xm:Student=new Student('小明',22)
  • 当我们给属性设定了protected受保护的时候他虽然不可以在类外部访问,但是却可以在它的子类访问,如上我们的age就成功的在子类中使用。

image.png

  • 值得一提的是,当构造函数修饰为 private 时,该类不允许被继承或者实例化。

🧃 只读属性

  • 我们可以给一个属性设定只读关键字,在变量前面加上readonly即可。
class People{//定义了一个名字为People的类
  readonly name:String;
  constructor(name:String){//constructor是一个构造方法,用来接收参数
      this.name = name;
  };
}
let xm:People=new People('小明')
console.log(xm.name)
xm.name='小卢' //无法分配到 "name" ,因为它是只读属性
  • 我们可以看到在外部可以访问只读属性但是不可以更改它的值。
  • 值得一提的是如果 readonly 和其他访问修饰符同时存在的话,需要写在其后面。

🍼 参数属性

  • 我们的修饰符和上面说到的只读属性可以在构造函数给参数赋值,这样可以简化我们的代码。
class People{//定义了一个名字为People的类
  public name:String;
  constructor(name:String){//constructor是一个构造方法,用来接收参数
      this.name = name;
  };
}
  • 等同于下面这种写法。
class People{//定义了一个名字为People的类
  constructor(public name:String){//constructor是一个构造方法,用来接收参数
      this.name = name;
  };
}

👋 写在最后

  • 本文也算是记录一下TypeScript的学习,接下来我会持续输出TypeScript相关的知识,大家可以一起来学习。
  • 如果您觉得这篇文章有帮助到您的的话不妨🍉关注+点赞+收藏+评论+转发🍉支持一下哟~~😛

🌅 往期精彩

「TypeScript」入门基础(一)🎯---安装与基础数据类型

「TypeScript」入门基础(二)🎯---联合类型与接口

「TypeScript」入门基础(三)🎯---数组类型与函数类型

「TypeScript」入门基础(四)🎯---类型断言

「TypeScript」入门进阶(一)✈️---类型别名、字符串字面量与元组