TS(TypeScript)基础知识二:函数规范 、类

512 阅读4分钟

这是我参与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、子类中必须要实现基类中的抽象方法;