这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
掌握基础知识可以通读vue源码
函数的声明
函数的声明既对函数的限制
基础类型
首先来看一个基础的例子:
//**注: bool和num3 都表示可选参数**
function add(num1: number, num2: number, bool?: boolean, num3 = 100): number {
return num1 + num2;
}
上面的例子中函数对 '参数' 和 '返回值' 做出规范;
再来看一个匿名函数:
let add = function(num1: number, num2: number) => number = function(num1: number, num2: number): number { return num1 + num2 }
解析: 在例子中箭头之前表示的是参数的类型;箭头之后表示的是返回值的类型;简化后如下(就是推断类型):
推断类型
返回值的类型可以推断出参数的类型
let add = function(num1: number, num2: number): number { return num1 + num2 };
剩余参数
和js中的arguments相比较:
相同:都是将函数中传入的多个参数放入一个数组集合中。
不同:ts是将除已经标明的参数外的其它参数放入到了集合中.
例子:
function sum(num1: number, ...otherNums:number[]):void{ console.log(num1, otherNums)}
sum(1,2,3,4)
//输出结果 1, [2, 3, 4]
上面的例子中就是将已经标明的num1之外剩余的其它参数放到了otherNums集合中;
方法重载
让我们先来看一个例子:
function reLoad(arg: any): any {
return arg
}
这个代码示例中可以看出reload方法可以接收任意类型的参数,并且可以接收任意类型的返回值。
但是同时它也失去了类型规范的意义;
假如我们需要一个求和函数,既可以接收string类型的数字,也可以接收number类型的数字。
这个时候我们就可以用到方法重载;
function reLoad(arg: string): string;
function reLoad(arg: number): number;
function reLoad(arg: any): any {
return arg
}
现在reLoad函数传参既可以传string也可以传number类型;
注:此时的any并不是代表着可以传递任意类型,而是表示重载列表的结束;
类
TS中的类采用的面向对象的方式,其基本的语法类型我将在下面各个类型的例子中展示
继承
先来看一个例子:
class Father {
public name: string;
public constructor(name: string) {
this.name = name
this.daily()
}
public daily() {
console.log(this.name + ':move bricks')
}
}
class Son extends Father {
age: number = 10
constructor(name: string, age?: number) {
super(name)
}
daily() {
console.log('drink milk ...')
}
}
let s: Son = new Son('son')
解析:
上面的例子中extends关键字表示子类Son继承自父类Father;
如Father类所示:在当前类里面的数据(name)、方法(daily)都可以通过this调用;
如果子类Son中使用到构造函数constructor的时候则必须要在构造函数中写明super()
super可以理解为父类Father的实例,可以在Son子类中通过super替换this调用父类方法和属性;
new出一个实例的时候可以认为调用的就是构造函数constructor;构造函数即为一个类的入口;
修饰符public
public修饰表示公开的,是可以自由访问的
类中如果不说明修饰类型的情况下,默认为public。所以public修饰符并不是必须的;
修饰符private
private修饰表示是私有的,是不能自由访问的
注:在当前类中可以访问。但是在类的外面无法访问,即使是子类中也无法访问;
class Father {
private name: string;
constructor(theName: string) { this.name = theName; }
run() {
console.log(this.name) //⑴
}
}
class Son extends Father {
constructor(name: string) {
super(name); //⑵
}
run() {
console.log(this.name); //⑶
super.run()
}
}
let son = new Son('son');
let father = new Father('father');
console.log(son.name, father.name) //⑷
上面这个例子中,父类中的name就是私有类型。
解析:
⑴:私有变量name在Father类中可以正常调用
⑵、super可以理解为父类的实例,也可以正常调用
⑶、Son子类中无法调用
⑷、实例化之后无论是子类还是父类的实例都无法调用(外部无法调用)
修饰符protected
public修饰表示保护类型,在当前类和子类中可以正常访问。但是外部无法访问。
例子:
class Father {
protected name: string;
constructor (name: string) {
this.name = name
}
}
class Son extends Father {
constructor(name: string){
super(name)
}
run() {
console.log(this.name) //⑴
}
}
let son = new Son('son')
console.log(son.name) //⑵
解析:
⑴处可以正常访问
⑵处不能访问
修饰符readonly
将属性设置为只读的
注:在给属性初始化(赋值)必须要在声明的时候,或者在构造函数中进行。
例:
class Father {
readonly name: string;
readonly age: number = 1;
constructor (name: string) {
this.name = name;
}
readonly age: number = 1;
constructor(readonly name: string) {
}
}
上面代码的简化写法
class Father {
readonly age: number = 1;
constructor(readonly name: string) {
}
}
解析:略
修饰符abstract
** 修饰符abstract表示抽象类、抽象方法(多态)**
抽象类只作为其它子类的基类存在,其中的方法父类自己不去实现。而由子类去实现
abstract class Father{
abstract run():any //不实现run方法;
}
class Son1 extends Father{
run(){
console.log(111)
}
}
注: 1、抽象类不能实例化;
2、abstract抽象方法只能放在abstract抽象类里面(class前面也必须要添加abstract修饰符)
3、子类中必须要实现基类中的抽象方法;