
3.2 循环
循环控制语句可以重复调用某段代码,直到满足某一条件退出或者永不退出,无限循环。一般在程序中除了条件判定以外,循环语句的使用率也是非常高的,因此我们必须掌握循环的基本用法。
在现实生活中,循环控制的例子也随处可见。例如,上学的时候,老师上课前用花名册点名,看有没有同学缺勤。学生花名册是一个包含学生学号和姓名等信息的列表。老师从第一个人开始,逐一向下进行点名,来上课的同学答“到”即可。
老师逐一循环对花名册中的每个同学进行点名的过程实际上就可以看作是一个循环的流程控制过程。老师要从花名册这个列表中查询出符合特定条件(缺勤的)的同学,必须借助循环和条件判断才能完成。
另外,我们的时钟计时也可以看作是一个循环,以分钟数和小时数为例,分钟数每隔60秒加1,然后判断分钟数是否为60,如果是,那么小时数加1,同时置分钟数为0,重新进行计时,等60秒后分钟数再加1,如此循环;如果不是,那么再过60秒后分钟数加1,如此循环,如图3.7所示。

图3.7 时钟计时循环流程图
在TypeScript中循环分为确定循环和不确定循环,常用的循环语句有for和while等。
3.2.1 for
在循环语句中,迭代次数是确定/固定的循环称为确定循环。for循环一般来说是一个确定循环的实现。在TypeScript中,循环中的for语法和JavaScript一致,下面给出一个数组testArray,通过循环将其各个元素打印出来。代码3-8给出了for的基本用法。
【代码3-8】函数forDemo1实现代码: ts008.ts
01 /** 02 * for语法演示 03 */ 04 function forDemo1(){ 05 let testArray = [20, 30, 40, 50]; 06 for (let i = 0; i < testArray.length; i ++) { 07 console.log(testArray[i]); 08 } 09 } 10 forDemo1(); // 20 30 40 50
在代码3-8中05行声明了一个名为testArray的数组,关于数组的具体语法,参见第4章。testArray数组有4个元素,分别是20、30、40和50。由于数组是一个可变长度的结构,要想打印出其中的每个元素,就必须利用循环才能完成。
提示
for循环中用let进行变量i声明,不要用var,防止污染外部作用域中的变量。
如果for循环中循环的次数较多,上面代码中的06行可以进行优化,从而提高执行效率。由于testArray.length在每次循环的时候都要重新计算一下,因此可以用一个变量暂存这个testArray.length的值,这样循环的效率就会提高,改进的代码如代码3-9所示。
【代码3-9】函数forDemo1改进代码: ts009.ts
01 /** 02 * for语法改进版演示 03 */ 04 function forDemo1(){ 05 let testArray = [20, 30, 40, 50]; 06 let len = testArray.length; 07 for (let i = 0; i < len; i ++) { 08 console.log(testArray[i]); 09 } 10 } 11 forDemo1(); // 20 30 40 50
在TypeScript中,循环中也支持for...in语法。for...in循环是对具体对象的键key和属性进行循环(不会忽略属性)。常用于打印对象或集合中键值对中的键名或是数组的下标及属性值,代码3-10给出了for...in的用法。
【代码3-10】for...in循环示例代码: ts010.ts
01 /** 02 * for...in语法演示 03 */ 04 interface Array<T>{ 05 prop: string; 06 } 07 function forDemo1(){ 08 let testArray = [20, 30, 40, 50]; 09 testArray.prop = "propValue"; //扩展属性 10 let len = testArray.length; 11 for (let item in testArray) { 12 console.log(item); // 0 1 2 3 prop 13 console.log(testArray[item]); //20 30 40 50 propValue 14 } 15 } 16 forDemo1();
在上面的代码3-10中,04~06行用interface Array<T>对数组泛型定义了一个prop字符型的属性,为了演示for...in可以打印出对象的属性。这一段涉及的知识点有数组、泛型和接口等,超出本章范围。这些知识点会陆续在后续章节进行介绍。
在TypeScript中还有一个for...of循环,是对具体对象中的值进行循环,而不是对键key的循环,并且忽略对象属性。代码3-11给出了for...of的用法。
【代码3-11】for...of示例代码: ts011.ts
01 /** 02 * for...in语法改进版演示 03 */ 04 interface Array<T>{ 05 prop: string; 06 } 07 function forDemo1(){ 08 let testArray = [20, 30, 40, 50]; 09 testArray.prop = "propValue"; //扩展属性 10 let len = testArray.length; 11 for (let item of testArray) { 12 console.log(item); //20 30 40 50 13 } 14 //console.log(item); //var item 可以打印出 prop 15 } 16 forDemo1();
提示
也可以用for实现无限循环,即for(;;)。
3.2.2 while
for循环一般用于有限循环中,循环的迭代次数往往固定。在现实生活中,有些时候我们不知道循环何时退出,循环中的迭代次数不确定或未知时可以使用不确定循环while和do...while实现。
以现实中的例子来说,假如现在已经是晚上11点了,我们从网站上下载一个非常大的视频文件,由于下载的速度是时刻变化的,没必要一直等待它下载完成后人工关闭电脑。此时可以设置一个任务,在此文件下载完成后自动关闭电脑。
这个过程实际上可以用while循环来解决下载文件完成后自动关闭电脑的问题。模拟代码如代码3-12所示。
【代码3-12】 while实现whileShutDownPC代码: ts012.ts
01 /** 02 * while语法演示 03 */ 04 function whileShutDownPC(){ 05 let percent: number = 0; 06 while (percent<100) { 07 console.log(percent+"%"); //当前进度% 08 percent++; 09 } 10 shutdownPc(); 11 } 12 function shutdownPc() { 13 console.log("执行关闭电脑操作"); 14 } 15 whileShutDownPC();
提示
while循环体中的代码可能不执行。
3.2.3 do…while
do...while循环类似于while循环,只是do...while循环不会在第一次循环执行时评估条件。将代码3-12中的while代码改成do...while的代码,如代码3-13所示。
【代码3-13】do...while实现whileShutDownPC代码: ts013.ts
01 /** 02 * do...while语法演示 03 */ 04 function whileShutDownPC(){ 05 let percent: number = 0; 06 do { 07 console.log(percent + "%"); //当前进度 08 percent++; 09 } 10 while (percent < 100); 11 shutdownPc(); 12 } 13 function shutdownPc() { 14 console.log("执行关闭电脑操作"); 15 } 16 whileShutDownPC();
提示
do...while循环体中的代码至少执行一次。