首页 > 技术文章 > H5前端技术文章 >

TypeScript系列-TypeScript语言特性(二)

更新时间:2018-12-10 | 阅读量(1,357)

### TypeScript系列 [02]-TypeScript语言特性(二) ### 流程控制结构 我们知道世界上所有的程序都可以简单划分为`顺序、分支和循环`这三种结构,使用这三种基本结构组合能够表示所有复杂的结构。**顺序结构**就是按固定的顺序来执行特定的代码(通常是自上而下执行),**分支结构**根据条件判断结果来确定执行那条路径,而**循环结构**用于处理需要重复执行的任务,通常循环结构由`初始条件、循环检测条件、循环体以及退出机制`组成。TypeScript语言中的流程控制结构和JavaScript保持一致。 **循环结构** TypeScript语言中的循环结构主要有:**`while循环`**、**`do..while循环`**、**`for..in循环`**以及常用的**`for循环`**,下面分别介绍并给出示例代码。 ```javascript //文件路径 ../02-流程控制结构/01-循环结构.ts //[001] while循环结构 //说明:while语句用来在满足判断条件的情况下重复执行一段代码,代码在执行的时候会先检查判断条件是否满足, //如果条件满足则执行循环体(更新条件变量),否则就结束当前循环执行后面的代码,重复这个过程 let i:number = 0; while(i < 5) { i++; console.log(i); } //[002] do..while循环结构 //说明:do...while循环结构能够保证循环体至少会被执行一次,当循环体执行完后,代码会检查判断条件是否满足, //如果满足条件则继续执行循环体,否则就结束当前循环执行后面的代码,重复这个过程 let j:number = 5; do{ j--; console.log(j); }while(j>0); //[003] for循环 //说明:执行for循环的时候的执行顺序为 //(1) 执行初始化语句,初始化变量n //(2) 检查是否满足循环条件 // A: 如果满足循环条件,那么就执行循环体,并跳转到(3) // B: 如果不满足循环条件,那么就结束当前循环,继续执行后面的任务 //(3) 更新循环变量,这里为n++操作 //(4) 跳转到(2) //关于break、continue和return //在循环体中,如果遇到break和return则表示结束循环(循环本身以及循环内后面的代码不再执行),执行循环后面的任务 //如果遇到continue则表示结束当前循环,继续执行后面的循环任务 for(let n:number = 0 ; n < 5; n++) { if(n === 3) continue; console.log(n); } //[004] for..in循环 //说明:for..in循环主要用于遍历代码中的对象 //注意:不推荐使用for..in循环来遍历数组或伪数组对象,因为它会把原型成员迭代出来。 let obj:any = {name:"zs",age:18,"des":"描述信息"}; for( let key in obj) { console.log("当前循环的key: "+key+" value:"+obj[key]); } ``` **分支结构** TypeScript语言中的分钟结构主要有`if..else语句`和`switch语句`,同JavaScript语言保持一致。下面还是贴出简短的代码示例: ```javascript //文件目录 ../02-流程控制结构/02-分支结构.ts //分支结构其实就是林中路在某个节点分叉为多条,而只能选择其中一条路继续走下去 //具体走哪条路就像是人生抉择,得出结选择论的部分被称为判断条件,是布尔类型的值(true/fasle) //[01] if条件语句结构 //当条件满足的时候,执行{}中的代码,否则就忽略 let temp:boolean = true; if(temp) { console.log("temp的值为true") } //..... //[02] if...else语句结构 //给定两条路,只能也必须走某一条 if(temp) { console.log("temp的值为true") }else{ console.log("temp的值为false") } //[03] if...else if...语句结构 //给定多条路,根据条件进行选择其中的一条 let i:number = 85; if(i >= 90) { console.log("优秀") }else if(i >= 80){ console.log("良好") }else if(i >= 60) { console.log("及格") }else { console.log("不及格") } //输出结果为:良好 //[04] switch结构 //switch语句接受一个表达式,会将表达式的值和case语句进行匹配,然后执行关联的语句块。 //为提高代码的可读性,避免魔法数字等出现,常结合枚举类型组织代码结构 enum Animal{ Dog, Cat, Pig } let animalType:any = Animal.Dog; switch(animalType) { case Animal.Dog: console.log("Dog: 汪汪汪!!!"); break; case Animal.Cat: console.log("Cat: 喵喵喵!!!"); break; case Animal.Pig: console.log("Pig: 呵呵呵!!!"); break; default: console.log("其他动物..."); } ``` ### 类(Class) 我们知道JavaScript本身支持面向对象编程,但实现的方式和其它典型面向对象编程语言截然不同,JavaScript中没有Class的概念,其多态、继承等特性主要依靠函数和原型机制来实现,这种实现机制让很多java/C++型开发者困惑不已。 从ES6开始,JavaScript将支持基于类的面向对象实现。 在TypeScript中,允许开发者现在就使用Class特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,而不需要等到下个JavaScript版本。 下面给出TypeScript中类的典型结构: ```javascript //文件路径 ../03-Class的使用/01-Class的典型结构.ts //类的定义 class Person{ age:number; //age属性 name:string; //name属性 constructor(name:string,age:number){ //调用时内部自动执行该代码段 this.age = age; this.name = name; console.log("执行内部的构造函数."); } getInfo(){ //getInfo方法 return "姓名:" + this.name + " 年龄:" + this.age } } //使用new来构造Greeter类的实例对象 var p = new Person("wendingding",18); console.log(p); ``` 上面的代码中,我们定义了一个名为Person的类,这个类拥有四个成员为:`name属性、 age属性、getInfo方法和constructor构造函数`。在Class的内部,我们可以通过 this来引用类中的成员。 当类被定义之后,我们可以使用 new来调用这个Class。 具体执行的时候,它会先调用Class中定义的构造函数执行初始化操作,并创建出一个当前类的实例对象返回。下面贴出上面代码编译为JavaScript代码后的结构: ```javascript var Person = /** @class */ (function () { function Person(name, age) { this.age = age; this.name = name; console.log("执行内部的构造函数."); } Person.prototype.getInfo = function () { return "姓名:" + this.name + " 年龄:" + this.age; }; return Person; }()); //使用new来构造Greeter类的实例对象 var p = new Person("wendingding", 18); console.log(p); ``` 通过观察可以发现,**`类其本质上是依靠闭包函数和原型对象来实现的`**。 注意:当我们在TypeScript语言中定义类的时候,该类中所有的属性和方法默认都是公开的。对于Class的其它细节,这里我们不做展开。 ### 接口(interface) TypeScript提供了接口机制。其实,TypeScript其核心原则之一就是`能够对值所具有的结构进行类型检查`,这种处理方式被称为“鸭式辨型法”。我们可以利用接口来为代码定义契约。 如果在设计某个函数的时候,我们希望该函数接受的参数对象(即函数的参数是一个对象)必须包含某个指定的属性,且类型固定。假设函数名为logNameAndOtherInfo,传递给该函数的对象参数必须要拥有name这个属性,且类型必须为string,我们可以尝试给出如下代码 ``` function logNameAndOtherInfo(obj:any){ console.log("name:"+obj.name); console.log("Other:默认的其它信息,这里不做处理"); } let obj1:any = {name:"文顶顶",age:18}; let obj2:any = {color:"red",age:18}; logNameAndOtherInfo(obj1); //name:文顶顶 //Other:默认的其它信息,这里不做处理 logNameAndOtherInfo(obj2); //undefined //Other:默认的其它信息,这里不做处理 ``` 观察上面的代码,我们会发现logNameAndOtherInfo函数无力在展示函数参数对象内部属性和类型方面有所作为。这种场景下,接口就可以派上用场。 ```javascript //文件路径 ../03-Class的使用/03-接口简单示例02.ts interface ObjWithNameValue { name: string; } function logNameAndOtherInfo(obj:ObjWithNameValue){ console.log("name:" + obj.name); console.log("Other:默认的其它信息,这里不做处理"); } let obj1:any = {name:234,age:18}; let obj2:any = {color:"red",age:18}; logNameAndOtherInfo(obj1); //name:文顶顶 //Other:默认的其它信息,这里不做处理 logNameAndOtherInfo(obj2); //undefined //Other:默认的其它信息,这里不做处理 ``` 除此之外,TypeScript中的接口与C#或Java里的基本作用一样,也能够用它来明确的强制一个类去符合某种契约。 ```javascript //文件路径 ../03-Class的使用/03-接口简单示例03.ts interface PersonInterface { name: string; getInfo(); } //类的定义,需要遵循接口的约定 class Person implements PersonInterface{ //报错:Property 'name' in type 'Person' is not assignable to the same property in base type 'PersonInterface'. //name:number; 错误的演示(类型和接口不一致) name:string; constructor(name:string){ //调用时内部自动执行该代码段 this.name = name; console.log("执行内部的构造函数."); } getInfo(){ //getInfo方法 return "姓名:" + this.name; } } //使用new来构造Greeter类的实例对象 var p = new Person("wendingding.com"); ``` 上面的代码中,我们定义了一个名为PersonInterface的接口,和一个实现了该接口的Person类,它能够确保实现了接口的类一定拥有指定的结构。 `说明`:**类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型匹配即可。** `备注`:该文章所有的示例代码均可以[点击在Github托管仓库获取](https://github.com/flowerField/TypeScript-Demo)
叩丁狼学员采访 叩丁狼学员采访
叩丁狼头条 叩丁狼头条
叩丁狼在线课程 叩丁狼在线课程