6. 重载
在旧 js 中,重载定义一个函数,在函数内根据传入的参数不同执行不同的逻辑;
而在 TS 中:先定义多个形参列表不同的同名函数声明,且先不实现函数体,
function 函数名():void; function 函数名(形参:数据类型):void; //void代表这个函数,没有返回值 //如果函数有返回值,必须将void改为返回值的具体类型 其次定义一个可实际执行多种任务的函数来支持上方多种重载的情况。 function 函数名(){ }
举例:使用重载实现三种支付方式;
// 先定义三种重载的情况 // void代表这个函数没有返回值 function pay(): void; function pay(money: number): void; function pay(card: string, pwd: string): void; function pay(...arr: any[]) { if (arr.length == 0) { console.log(`手机支付`); } else if (arr.length == 1) { console.log(`微信支付`); } else { console.log(`刷卡支付`); } } pay(); //手机支付 pay(10000); //微信支付 pay("123456", "000"); //刷卡支付 //pay(123,456) 不符合最初定义的三种重载情况时直接报错
运行结果如下:
7. class
class 类型的定义:
class 类型名{ 属性名1:数据类型=初始值; 属性名2:数据类型=初始值; constructor(形参1:数据类型, 形参2:数据类型){ this.属性名1=形参1; this.属性名2=形参2; } 方法名():数据类型{ ... } }
注意:TS 中 class 的属性必须在构造函数上方提前定义并指定数据类型,这样才能在构造函数中执行 this.属性名=赋值。
举例:定义学生类型,描述学生统一结构;
class student { sname: string = ""; sage: number = 0; constructor(sname: string, sage: number) { this.sname = sname; this.sage = sage; } intr(): any { console.log(`我是${this.sname},我今年${this.sage}岁。`); } } var zhang = new student("张飞", 52); zhang.intr(); console.log(zhang);
运行结果如下:
class 中的所有成员无论在 class 内还是在子类型内或者在全局,都可用 ”this.属性名” 或” 对象名.属性名”方式访问;但如果有些数据不想让随意访问,就需要用到访问控制修饰符。
访问修饰符是专门修饰一个属性或一个方法的可用范围的关键字;格式如下:
访问控制修饰符 属性名 : 数据类型 = 初始值
访问控制修饰符的三种类型:
(1)public 公有(默认),表示子类型和类外部都可访问到的类成员;
(2)protected 受保护,表示只有父子类型范围内才能使用,外部不可用;
(3)private 私有,表示仅 class 内可用,子类型和外部都不能用。
举例:通过一个一家人管钱的例子说明访问控制修饰符的三种类型;
class Father { public moneyPublic: string = "Father公开的钱"; protected moneyProtected: string = "Father和Son的钱"; private moneyPrivate:string="Father私有的钱"; fatherPay() { console.log(`Father用${this.moneyPublic}给自己买了一包烟!`); console.log(`Father用${this.moneyProtected}给自己买了一块表!`); console.log(`Father用${this.moneyPrivate}给自己买了一身衣服!`); } } class Son extends Father { sonPay() { console.log(`Son用${this.moneyPublic}给自己买了一个玩具!`); console.log(`Son用${this.moneyProtected}给自己买了零食!`); } } var f1 = new Father(); var s1 = new Son(); f1.fatherPay(); s1.sonPay(); // 全局mother console.log(`mother用${f1.moneyPublic}给自己买了一个包包!`);
运行结果如下:
8. 接口
如果希望开发人员一定要按照架构师的要求实现程序结构时,都用接口来规范。首先是定义接口:
interface I接口名{ 规定的属性名: 类型; 规定的方法名(参数:数据类型):返回值; }
接下来“实现接口”:
class 类型名 implements I接口名{ //必须包含接口中规定的属性和方法 }
举例:使用接口规范实现飞机飞行;
interface IPlane { x: number; y: number; fly(): void; } class Plane implements IPlane { x: number = 0; y: number = 0; score: number = 0; constructor(x: number, y: number, score: number) { this.x = x; this.y = y; this.score = score; } fly(): void { console.log(`飞到x=${this.x},y=${this.y}的位置`); } getScore(): void { console.log(`击落敌机得${this.score}分`); } } var p = new Plane(100, 20, 20); p.fly(); p.getScore(); console.log(p);
运行结果如下:
9. 模块化开发
模块化开发即哪个文件想使用另一个文件的内容,直接 引入即可。
只导出一个接口或类型时:
//先创建类型/接口 //导出 export default 类型名/接口名 //引入 import 类型名 from “相对路径” 导出多个接口或类型: //先创建多个类型/接口 //导出 export { 类型名, … } //引入 import { 类型名, … } from “相对路径”