这是我参与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 - 翻译过来意思是
受保护的
用于修饰该属性或者方法是受保护的,不可以在它的类外部调用,但是可以在子类调用和访问。
- public - 翻译过来意思是
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
就成功的在子类中使用。
- 值得一提的是,当构造函数修饰为
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」入门基础(二)🎯---联合类型与接口