需求:输出“飞哥真帅”100遍啊100遍!
不要傻乎乎的复制粘贴100遍:
console.log("飞哥真帅");^_^,程序员厌恶ctrl+c / ctrl+v !
使用 while 关键字:
while (true) { console.log("飞哥真帅"); }
这就是循环(loop),循环又被称之为“迭代(iterate)”,是指计算机反复执行一段的过程。
循环和分支一起,构成了现代主流编程语言面向过程的核心。
现在这样直接给true值,就是一个永远不会停止的死循环。
死循环一般都是应该避免的,所以我们需要在while后面的()中可设定循环终止条件。
----------------------
【教学备忘】2022年7月13日:下一期把循环和数组分别拆成两章,这里引入break/continue跳出循环的语法
----------------------
为了实现100遍(不要这样自恋,为了便于观察,改成5遍吧)的效果,我们通常要使用累加器/计数器:
let i = 0; //i就是累加器,常用的起始值为0 while (i < 5) { //满足条件:继续循环;否则跳出 i++; //每循环一次,累加一次 console.log("飞哥真帅"); }@想一想@:按上面的代码,"飞哥真帅"会被输出几次?为什么?
注意:一定要仔细的确定循环中的边界值,比如:
i 除了在while中作为累加器使用,也可以作为普通变量使用,比如:
let i = 0; while (i < 5) { i++; console.log("第" + i + "次:飞哥真帅"); }
以及更复杂的功能,比如:
取1+2+3+...+100的值:(不要用人脑代替电脑,想着什么(1+100)*100/2……)
使用循环的关键是:找到一个固定的运算规律,每次循环都这样运行……
let i = 0, sum = 0; while (i < 100 ) { /*let*/ sum += i; /*let的声明究竟该放在哪里?*/ i++; //i究竟该哪里? } console.log(sum);
断点演示:
在循环中进行调试的利器,可以更精确的指定在何时击中断点。
使用方式:断点上右键 - edit breakpoint - 输入条件表达式:
和while非常类似,但它首先会在do里面执行一次:
do { console.log(i); sum += i; i++; } while (i <= 100); console.log(sum);
实际上更常用的是for循环,比如:
for (let i = 0; //迭代初始值(init) i < 5; //结束条件(expression) i++ //步长(post-loop),每次循环之后运行 ){ console.log("第" + i + "次:飞哥真帅"); }
实际上就是把累加器i的声明和累加都放在了for后面的()里。
断点演示:for循环的运行过程
而上面的求和运算就可以写出:
for (let i = 1; i <= 100; i++ ){ sum += i; }
如何选择?
花括号还可以确定变量的作用域(scope),即声明的变量,只能在一个“特定的区域”使用:
从变量声明开始,到声明变量所在{}的结束为止(如果是声明在{}中的话):
{ let sum = 3 + 2; { console.log(sum); //还是OK的 //let sum = 5; //重复声明,不行,仍在之前sum的作用域中 } } //sum++; //不行,超出sum作用域
但是,for循序中 i 的作用域,是在for循环体中:
for (let i = 0; i < 3; i++) { console.log(i); } console.log(i); //不行,用不了啦 //两个for循环,都使用同名的i,但互不干涉 for (let i = 5; i < 10; i++) { console.log(i); }
这也是推荐优先使用for循环的原因。@想一想@:使用while循环会怎么样?
数组(array)是一种常用的数据结构(数据容器),里面有序的存放着多个元素。
这是最常用的数组。之前我们把变量想象成一个盒子,那么现在数组就是一“排”盒子:
声明的方法非常简单:
let numbers = [1, 9, 7, 3, 15, 5, 4, 6];
获取数组中的元素,或者给数组中元素赋值,需要使用方括号([]),并在其中指定该元素在第几位(下标)。
注意:且数组的下标都是从0开始的,所以:
numbers[0] //第1个,值为1 numbers[1] //第2个,值为9 numbers[2]=100 //将第三个元素值更改为100 numbers[8]=986 //新增加第9个元素,值为986
数组中一共有多少个元素可以用.length取出,比如:
numbers.length //8
for (let i = 0; i < numbers.length; i++) { console.log(numbers[i]); }
注意:i 的初始值和循环结束条件,这几乎已成“定式”,^_^
PS:JavaScript中并没有直接支持多维数组 ……
需求:在数组中查找某个值,比如说 int[]{8,7,9,10,2,4,5} 中找到10。
@想一想@:有没有问题?
思路:把数组中的元素挨个挨个的拎出来,一个一个的和10进行比较。
在循环中使用条件判断,就可完成这个功能:let seed = 7; for (let i = 0; i < numbers.length; i++) { if (numbers[i] == seed) { console.log("找到了……"); //找到了,怎么办? } }
注意:作为一个专业(professional)的程序员,源栈的同学们,这时候一定要注意:
明确模糊的需求:
for (int i = 0; i < studentIds.Length; i++) { if (studentIds[i] == 10) { Console.WriteLine($"找到了,在数组中第{(i + 1)}位"); } else { Console.WriteLine("没找到"); } }
演示:错误效果
问题的关键:只有当所有的元素都查找了一遍都没找到,才算没找到。肿么办?
let /*hasFound=false,*/ index=-1; for (let i = 0; i < numbers.length; i++ ){ if(numbers[i]==155){ //hasFound = true; index = i; } } if(/*hasFound*/ index > -1){ console.log("找到了,在第"+ (index+1) + "位"); }else{ console.log("没找到"); }这种方案的问题是引入了一个额外的变量。
for (let i = 0; i < numbers.length; i++ ){ if(numbers[i]==155){ console.log("找到了,在第"+ (i+1) + "位"); } else{ //已经是最后一个元素啦! if(i == numbers.length-1){ console.log("没找到"); }//else nothing } }
问题就在于当我们找到了要找的那个值后,还有必要继续循环比对么?断点演示……
好代码三大指标:安全、性能、可维护性。
三者不可兼得!
排名不分先后,权重因地制宜。
性能问题是最隐蔽的,你不去测量,好像一切OK。
Stack Overflow的例子:访问量这么高的一个网站,为什么就只要这么几台服务器?
并不是他们用了什么了不起的技术(相反,他们还用了很多程序员看不起的ASP.NET和SQL Server,而且数据库不是流行的水平扩展而是垂直升级),而是他们的代码没有性能浪费。
假设我们的需求是只要找到一个就OK,不用管其他,那么我们就需要使用:(断点演示)
if(numbers[i]==15){ console.log("找到了,在第"+ (i+1) + "位"); break; }
for (let i = 0; i < numbers.length; i++ ){ if( i == 3 ){ //break; continue; } console.log(numbers[i]); }
if(i!=3){ console.log(numbers[i]); }
本质上,所有的需求都是而且只能是通过计算机的循环/分支实现的,同学们要逐步转换思维,学会用循环分支来实现各种编程需求。
不要:我一眼望过去就知道了……想象有很多很多数据,你一眼望不到头的那么多,怎么办?
是不是只能:
直到所有元素比对完毕?
let max = numbers[0]; //max存放最大值 for (let i = 0; i < numbers.length; i++) { if (max < numbers[i]) { max = numbers[i]; }//else nothing } console.log(max);
输出这样一个三角形:
* *** ***** *******
这就需要用到循环的嵌套。
关键思路:
//i: 第i排; for (let i = 1; i <= 4; i++) { let stars = ""; //j: 多少个星 for (let j = 0; j < 2*i-1; j++) { stars = stars + "*"; } console.log(stars); }
注意:按惯例,循环嵌套中的累加器变量名按 i,j,k……依次命名,不要乱写。
333 4444 55555 666666
多快好省!前端后端,线上线下,名师精讲
更多了解 加: