Javascript 流程控制语句和算法
TIP
本章节我们一起学习流程控制语句,所谓流程控制语句,就是指我们可以通过这些语句来控制代码按照什么样的顺序结构来执行。
在JS中流程控制语句主要有三种结构:顺序结构,分支结构,循环结构,这三种结构代表三种不同的代码执行顺序。
顺序结构
代码默认执行结构就是按顺序结构,从上往下依次执行。
分支结构语句
- if 语句
- switch 语句
循环结构语句
for 语句
while 语句
do while 语句
这些都是接下学习的重点,首先学习if 语句
一.IF 语句
1.最简单的if语句
- if 是如果的意思,如果 () 括号中条件成立,则就执行 {} 大括号中的语句块
- 如果不成立,则啥也不做
if (条件) {
// 当条件为真,则执行里面的代码
//语句块.....
}
// if语句后面的代码
注
- 这里的语句块可能是一行代码,也可能是一个多行代码
- () 括号里的条件可以是任何值或任何表达式,并且求值结果不一定是布尔值
- 但JS内部会自动调用Boolean()函数,将这个表达式返回布尔值
- 如果条件求值为true,则执行{}里面的代码,如果条件求值为false,则啥也不做,执行 if语句后面的代码
1.1 if语句写法
<script>
//3>2 条件表达式,返回值为true
if (3>2) {
console.log("3>2")
}
</script>
<script>
//null最终被转换成Boolean值,返回值为false,所以不会执行{}中的语句
if (null) {
console.log("3>2")
}
</script>
1.2 要注意区分那些是属于if语句体中的语句
<script>
if (3>2) {
console.log("3>2")
}
//以下是if语句体外的语句,不管if中的条件是否满足,他都会执行
console.log("我是语句体外的语句")
</script>
1.3if语句中的简写
- 如果if 语句体中只有一条语句,可以省略大括号和换行
- 如果超过一条语句,是万万不能简写的,简写会造成编译错误
<script>
if (2<3) console.log("2<3成立,在控制台输出");
if(2>3) console.log("2>3不成立,不在控制台输出");
console.log("我与if无关,我永远出来");
</script> //2<3成立,在控制台输出 我与if无关,我永远出来
2.if-else 语句
- 如果条件求值为true,则执行语句块1中的内容,否则执行语句块中2的内容
if (条件) {
// 当条件为真,则执行里面的代码
//语句块1.....
}else {
//当条件为false,执行这里代码
//语句块2
}
代码演示:
<script>
var a = 3;
if (a>2) {
console.log(a + ">2"); // 输入3>2
} else {
console.log(a + "<2");
}
</script>
案例实践:判断用户输入的数是偶数还是奇数
- 如果一个数除以2能整除,也就是余数为0,就是偶数,否则就是奇数
- 但是用户啥也不输,'‘和’ '也会被转成0,这里暂时不做讲解,下面案例中会完善
<script>
//弹出窗口,让用户输入内容
//让用户输入一个数字,然后用一个变量接受
var num = Number(prompt("请用户输入一个数字"));
//上面num接收过来的值,是字符串类型,不过num%2会自动做隐式类型转换,转换成数字
if (num%2 == 0) {
alert(num + "是一个偶数")
}else {
alert(num + "是一个奇数")
}
</script>
3.if-else if 多条件分支语句
- 如果条件1成立,则执行语句1,后面的就不看了
- 如果条件不1成立,则看条件2,如果条件2成立,则执行语句2,如果不成立,则执行语句3
if (条件1) {
//条件2为真,执行这里的代码
//语句1
} else if (条件2) {
//条件1为假,条件2为真,执行这里的代码
//语句2
} else {
// 条件1和2都为假,执行这里的代码
//语句3
}
案例实践1:根据用户输入的成绩,判断用户在哪个成绩档次
分数 | 档次 |
---|---|
90-100 | 优秀 |
89-70 | 良好 |
69-60 | 一般 |
0-59 | 不及格 |
<script>
var score = prompt("请输入你的考试成绩!");
if (score >=90) {
alert("成绩优秀");
} else if (score >=70) {
alert("成绩良好");
} else if (score >=60) {
alert("成绩良好");
} else {
alert("成绩不及格");
}
</script>
<script>
var score = prompt("请输入1-100之间的数字");
if (score >=90 && score <=100) {
alert("成绩优秀");
} else if (score >=70 && score < 90) {
alert("成绩良好");
} else if (score >=60 && num < 70) {
alert("成绩良好");
} else {
alert("成绩不及格");
}
</script>
案例2:判断用户输入内容是否为数字
代码实现思路分析:
- 用户输入的内容,都是字符串,我们要判断是否为数字,肯定是要把类型转换成数字,看能不能转成功.
- 将字符串转换为数字有很多方法;Number(),parseInt(),+号我们选哪个呢?
- Number()和+号都可以,不管字符串是不是纯数字,都会转成NaN,纯数字字符串都会转成数字,但空字符串和" " 空格不行,会被转换成0
- 所以接下来,接下来先过滤不是纯数字字符串,再过滤’'空格,剩下的就是纯数字字符串了
- 要判断**Number()**函数转换后的结果是不是NaN和数,有两种方法
- isNaN用来判断一个数是不是数字,而NaN正好不是数字,还可以用NaN不自等的方法判断.
- 接下来过滤"“,” "空格和数字,可以通过parseInt()和isNaN结合
- 剩下的就是纯数字字符串了
<script>
var num = prompt("请输入一个数字");
//如果Number能转成一个数字,那么isNaN返回结果是false
//如果Number不能转成一个数字,那么他就是字符串,字符串被转成NaN,所以为true
if (isNaN(Number(num))) {
alert("这不是一个数字"); // 这里过滤的是字符串,但不能过滤' '
} else if (isNaN(parseInt(num))) {
alert("不是一个数字");
} else {
alert ("是一个数字"); // 剩下的就是数字
}
</script>
- 封装成方法使用
<script>
function isNumber(num) {
if (isNaN(+num)) {
// 如果条件成立,则num不是纯数字字符串,但不能过滤'' 空格
return false;
} else if (isNaN(parseInt(num))) {
// 识别空格或者没有输入任何值
return false;
} else {
return true;
}
}
</script>
4.if,if-else,if-else if语句的嵌套
if() {
// 语句1
// 语句中可以嵌套 if(){}else{ } 或 if()else if(){}等if语句
}else {
//语句2
// 语句2中可以嵌套 if(){}else{ } 或 if()else if(){}等if语句
}
5.if 嵌套案例实践
案例实践1:BMI肥胖指数计算
- BMI指数(Body Mass Index 身体质量指数) 是用体重(以公斤为单位)除以身高(以米为单位)的平方得出的数字,是目前国际上常用的衡量人体胖瘦程度以及是否符合健康的标准
- BMI指数 = 体重/身高*身高
BMI值 | 分档 |
---|---|
低于18.5 | 过瘦 |
18.5-24(不含) | 正常 |
24-28(不含) | 过胖 |
28-32(不含) | 肥胖 |
大于等于32 | 非常肥胖 |
<script>
// 要求用户输入身高,强制转换为数字
var height = parseFloat(prompt("请输入你的身高多少米"));
//要求用户输入体重(公斤)
var weight = parseFloat(prompt("请输入你的体重"));
var bmi;
if (isNumber(height) && isNumber(weight)) {
// 得到BMI指数
bmi = weight / (height * height);
// 对BMI指数做判断
if (bmi < 18.5) {
alert("过瘦");
} else if (bmi < 24) {
alert("正常");
} else if (bmi < 28) {
alert("过胖");
} else if(bmi < 32) {
alert("肥胖");
}else {
alert("非常肥胖")
}
} else {
alert("输入有误");
}
function isNumber(num) {
if (isNaN(+num)) {
// 如果条件成立,则num不是纯数字字符串,但不能过滤'' 空格
return false;
} else if (isNaN(parseInt(num))) {
// 识别空格或者没有输入任何值
return false;
} else {
return true;
}
}
</script>
案例实践2:判断用户输入的数是奇数还是偶数
<script>
var num = prompt("请用户输入一个数字");
if (isNumber(num)) {
if ((num & 1) == 1) {
alert("是一个奇数");
} else {
alert("是一个偶数");
}
}
// 封装好的用来判断用户输入的数是否是纯数字
function isNumber(num) {
if (isNaN(+num)) {
// 如果条件成立,则num不是纯数字字符串,但不能过滤'' 空格
return false;
} else if (isNaN(parseInt(num))) {
// 识别空格或者没有输入任何值
return false;
} else {
return true;
}
}
</script>
案例3:游乐园门票计算
- 某游乐园的门票价格如下表
- 请用户输入年龄和星期几,弹出对话框显示出门票价格
- 星期日到星期一,分别用阿拉伯数字0,1,2,3,4,5,6表示
年龄大于12岁 | 年龄小于等于12岁 | |
---|---|---|
平日 | 100 | 50 |
周末 | 200 | 150 |
两种实现思路
- 左图:先判断星期几,再判断年龄
- 右图:先判断年龄,再判断星期几
<script>
// 第一种思路:先判断当前是周日还是平日
//然后再判断用户年龄,最后再输入门票
// 让用户输入日期
var week = prompt("请输入今天是星期几"); // 0,1,2,3,4,5,6
var age = prompt("请输入年龄");
//先判断是周几
if (week == 0 || week == 6) {
//周末
if (age>12) {
alert ("周末,门票价格"+200);
} else {
alert("周末门票价格"+150);
}
} else {
//平日
if (age>12) {
alert("平日,门票价格"+100);
}else {
alert("平日,门票价格"+50);
}
}
//获取日期
var date = new Date();
console.log(date.getDay()); // 0-6 星期天 六 1,2,3,4,5
</script>
注
在实际业务场景中,年龄也不会让用户自己输入,而是通过扫描身份证或输入身份证号识别.
二.switch语句
- 除if语句之外,JS还提供了另外一种选择语句:switch语句
switch (表达式或变量) {
case 值1:
//执行语句1....
break;
case 值2:
//执行语句2....
break;
default:
//执行语句3....
break;
}
1.switch 语句基本用法
- switch后面的表达式和变量会依次与case后面的值进行比较,比较时是全等比较,因此不会做数据类型转换
- 如果比较结果为true,就会执行当前case下面的执行语句,执行到break关键字,就会跳出switch语句,退出执行.
- 如果比较结果为false,则继续往下比较,如果所有结果都为false,则最后会执行default下面的语句.
- 当然default可以省略不写
<script>
var a = 1; //a的类型是数字,这里可以尝试把值换为1,3看下结果
switch(1) {
case '1': // 1与'1'在全等比较时,返回false 不成立,则继续与下一个case后面值作比较
alert('这里是字符串1,匹配失败');
break;
case 2: // 1与2作全等比较时,false,继续与下一个case后面值作比较
alert('这里是2,匹配失败');
break;
case 1: // 1与1全等,则执行这个case后面的语句
alert('这里是1,匹配成功');
break;
default:
alert('找不到相匹配的内容');
break;
}
</script>
以上代码最后执行结果,最后在页面弹出弹窗,弹窗内容为这里是1,匹配成功
在实际开发中,**switch()**括号中表达式的值,经常以变量形式出现
2.break不写会有什么影响?
- 如果不写break,则会在匹配成功之后,后面所有case都将被视为匹配,直到遇见break,才会退出.
- 所有switch语句中,程序员必须主动调用break来跳出switch语句体
<script>
var a = 1;
switch(a) {
case 0: // 全等匹配失败
alert('这里是0,匹配成功'); // 这里不会弹出来
case 1: //全等匹配成功,下面代码会执行
alert('这里是1,匹配成功');
//这个case中没有break,则会将,后面所有case都将被视为匹配,直到遇见break,才会退出.
case 2:
alert('这里是字符串2,匹配成功'); //这里会弹出来
break; // 到这里退出
case 3:
alert('这里是字符串1,匹配成功');
default:
alert('找不到相匹配的内容');
break;
}
</script>
以上代码,最后会在页面中弹出’这里是1,匹配成功’,确认后,又会接着弹出’这里是字符串2,匹配成功’
3.多条case共用一个语句体
switch语句与if语句的区别,switch语句的用途:当一个变量被分类讨论的情形
- 判断当前是休息日,还是工作日
- 数字0-6表示星期日-星期六
if语句形式
<script>
var week = 0;
if (week == 1 || week == 2 || week == 3 || week == 4 || week == 5) {
alert("现在是工作日,记得要早起哦!");
} else if (week == 0 || week == 6) {
alert("今天是周末,尽情的享受吧");
}
</script>
switch语句
<script>
var week=4;
// var week=new Date().getDay(); 自动获取当天是星期几的方法
switch(week){
case 1:
case 2:
case 3:
case 4:
case 5:
alert("现在是工作日,记得要早起哦!");
break;
case 6:
case 0:
alert("今天是周末,尽情的享受吧");
break;
}
</script>
4.switch表达式值为布尔值
- 判断一个人是否是未成年人,如果满18,就是成功,否则是未成年人
<script>
var a=Number(prompt('请输入你的年龄'));
switch(true){
case a>=18:
alert('成年人');
break;
default:
alert('未成年人');
break;
}
</script>
5.switch的嵌套
<script>
switch(){
case 值1:
//执行语句
break;
case 值2:
//执行语句
switch( ){
case 值1:
//执行语句
break;
//....
}
break;
//....
}
</script>
6.switch嵌套案例
案例:根据年份和对应的月份,判断月份天数
- 1,3,5,7,8,10,12月,每月31天
- 4,6,9,11月,每月30天
- 当年为闰年,2月29天,其他年份,2月28天.
- 判断是不是闰年,能被4整除,但不能被100整除 或 能被100整除,也能被400整除
<script>
var year = 2023;
var month =Number( prompt("请输入你想要知道的月份"));
switch(month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
alert("当月有31天");
break;
case 4:
case 6:
case 9:
case 11:
alert("当月有30天");
break;
case 2:
var isRunNian =
(year % 4 === 0 && year % 100 !== 0) ||
(year % 100 === 0 && year % 400 === 0);
//if (isRunNian) {
// day = 29;
// } else {
// day = 28;
// }
switch(isRunNian) {
case true:
alert("当月有29天");
break;
case false:
alert("当月有28天");
break;
}
break;
default:
alert("你输入的月份有误")
}
</script>
7.if 语句和switch语句应用场景总结
条件判断句 | 应用场景 |
---|---|
if 语句 | 根据条件做出判断,符合条件做什么,不符合条件做什么 |
switch语句 | 一个变量存在多个值的情况,根据不同的值分别来讨论 |
三.for循环
如果我们想在页面中,重复执行某个操作时,我们就可以用到for循环语句.
- 比如你同一个女孩表白,他说,你必须要说100次“我爱你”,她才答应做你女朋友,那怎呢办呢?
- 最简单的方式就是把声音录到大喇叭里,重复的播放100次。
我们来看下,如果没有for循环,那之前学到的东西,我们要在
<script>
console.log("我爱你!");
console.log("我爱你!");
console.log("我爱你!");
//此处省略97次 console.log("我爱你!");
</script>
- 但有了for循环,我们就可以简化程序的写法
<script>
// 以下代码执行完,最后在控制台,输出100次“我爱你”
for (var i = 0; i < 100; i++) {
console.log("我爱你!" + i);
}
</script>
1.for语句的用法
首先我们来学习下for语句的语法,下面这个for循环语句有哪些组成成分
<script>
//在控制台输出0-9的数字
for(var i = 0; i < 10; i++) {
console.log(1);
}
</script>
for 的圆括号中有3个表达式:
- 表达式 var i = 0; 表示定义一个循环变量i,赋值为0
- 表达式i < 10; 表示继续执行循环的条件,只要这个条件为真,则会一直执行下去
- 表达式i++ 用来更新循环变量,使循环变量的值越来越趋向于终点
2.for语句的执行机理
我们先来看一个简单的for循环语句:
- 首先会执行语句1
- 然后判断语句2是否满足,如果满足则进入循环体,执行语句3,如果不满足,则退出循环体
- 语句体中的语句执行完毕后,执行语句4
- 再次判断语句2是否满足,如果满足则进入循环体,执行语句3,如果不满足,则退出循环体
- …依次继续循环执行
3.准确遍历for循环
根据for循环执行原理,必须要会准确遍历for循环
案例1:
<script>
for (var i = 3; i <= 15; i += 3) {
console.log(i);
}
// 当i = 3; 3 <= 15时,满足条件,输出3,再执行i+=3更新循环变量,得到 i=6
//再次判断 i<15这个条件,即6<=15,满足条件,输出6,再执行i+=3更新循环变量,得到 i=9
//再次判断 i<15这个条件,即9<=15,满足条件,输出9,再执行i+=3更新循环变量,得到 i=12
//再次判断 i<15这个条件,即12<=15,满足条件,输出12,再执行i+=3更新循环变量,得到 i=15
//再次判断 i<15这个条件,即15<=15,满足条件,输出15,再执行i+=3更新循环变量,得到 i=18
//再次判断 i<15这个条件,即18<=15,不满足条件,退出for循环
</script>
案例2:
<script>
for (var i = 15; i > 2; i -= 3) {
console.log(i);
}
// 当i = 15; 15 > 2时,满足条件,输出15,再执行i-=3更新循环变量,得到 i=12
//再次判断 i>2这个条件,即12>2,满足条件,输出12,再执行i-=3更新循环变量,得到 i=9
//再次判断 i>2这个条件,即9>2,满足条件,输出9,再执行i-=3更新循环变量,得到 i=6
//再次判断 i>2这个条件,即6>2,满足条件,输出6,再执行i-=3更新循环变量,得到 i=3
//再次判断 i>2这个条件,即3>2,满足条件,输出3,再执行i-=3更新循环变量,得到 i=0
//再次判断 i>2这个条件,即0>2,不满足条件,退出for循环
</script>
案例3:
<script>
for (var i = 2; i < 12; i += 3) {
i +=4;
console.log(i);
}
// 当i = 2时,满足条件2 < 12,i +=4,输出 6,再执行i += 3,得到 i=9
// 当i = 9时,满足条件9 < 12,i +=4,输出 13,再执行i += 3,得到 i=16
// 当i = 16时,不满足条件,退出for循环
</script>
案例4:
for (var i = 1; i < 10; i++) {}
//不在循环体中,输出循环结束时i的值
console.log(i); // 10
案例5:
for (var i = 1; i < 10; i--) {
console.log(i); // i永远都会小于10,所以会进入死循环
}
案例6:
for (var i = 10; i < 4; i++) {
//没有任何输出,一开始就不满足条件
console.log(i);
}
//在循环体外输出 i=10
console.log(i);
4.for循环案例
- 累加器:求1-10之间所有数字的和
<script>
//这楼里一定要赋初始值为0,否则为undefined,在做加法运算时,转换成NaN,NaN与任何数相加都得NaN
var sum=0;
for(var i=1;i<=10;i++){
sum+=i; //等同于sum=sum+i;
}
console.log(sum); // 55
</script>
- 字符串的拼接(在页面输入10颗星星)
<script>
//定义一个新变量 累加器的概念
var str = '';
for(var i=0;i<10;i++) {
str = str +'⭐';
// 1 str ='⭐'
// 2 str='⭐⭐'
// 3 str='⭐⭐⭐'
}
console.log(str); //⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
</script>
5.for循环的嵌套
- for循环中可以嵌套for循环
<script>
for(var i=0;i<5;i++){
//...循环体
for(var j=0;j<5;j++){
//...循环体
}
}
</script>
- for循环嵌套的执行原理
- 从最外层for循环开始执行,执行到内部for循环时,要把内部for循环执行完
- 再更新最外层的循环变量,然后判断条件是否成立,成立则执行循环体中代码,进入内部循环
- 内部循环全部执行完,再更新最外层的循环变量,重复上面过程
<script>
for(var i=1;i<=3;i++){
for(var j=1;j<=5;j++){
console.log("i=" + i + ",j=" + j);
}
}
// 首先i=1;i<=3成立,则进入循环体,执行循环体中的for
// j=1;j<=5成立,则进入循环体,执行循环体中的代码 console.log("i=" + i + ",j=" + j);
// 执行成功后,j++得到j=2,再判断2<=5成立,则再执行循环体中代码
//重复上面过程,当j的值为6时,退出第二个for循环体,进入第一个for循环,i++得到i=2,2<3成立
//进入第二个for循环,首先j=1,1<5成立,则进入第二个for循环...
//最后当i=4时,退出整个for循环
</script>
6.for循环嵌套案例
6.1打印如下图片
- 理解最外层for循环代表行,最内层for循环代表列
<script>
var str='';
//行
for(var i=0;i<5;i++){
// 列
for (var j=0;i<7;j++) {
str +="⭐";
}
str +="\n";
}
console.log(str);
</script>
6,2打印99乘法表
- 在理解最外层for循环代表行,最内层for循环代表列的基础上
- 要找出行与列对应的关系(这是最难也是必须要攻克的)
document.write() 把内容添加到html
<style>
span {
background-color: #ddd;
margin: 5px 5px;
display: inline-block;
height: 50px;
line-height: 50px;
width: 100px;
text-align: center;
}
</style>
<script>
//九九乘法表
//1行--1列 2行--2列 3行--3列 4行--4列....9行--9列
for(var i = 1; i<9;i++){
for(var j = 1;j<=i;j++) {
document.write("<span>" + j + "*" + i + "=" + j * i+ "</span>");
//1*1=1
}
document.write("<br/>");
}
//第一行:i=1, 1 * 1 = 1 </br/>
//第二行 i=2 2 * 1 =2 2 * 2 = 4 </br/>
//第三行 i=3 3 * 1 = 3 3 *2=3 3*3=9 </br/>
</script>
总结规律
最外层for循环对应的行数
最内层for循环对应每一行中的列
在执行for嵌套中,首先要找的就是行和列的关系(当然最难的就是找出列和行之间的关系)
有了这个规律,我们想打印任何图形都变得简单
6.3打印下表中的3个图形
document.writeln是向文档中写入一串文本,并紧跟着一个换行符(换行符会被编译成一个空格效果)
document.writeln("刘宇宁"); document.writeln("刘宇宁");// 刘宇宁 刘宇宁
- 等腰三角形
<script>
// 等腰三角形
//外层控制行 内层控制列
// 1行---4列 2行---3列 3行--2列 4行--1列 5行--0列
for (var i = 0;i<5;i++){
//控制每一行左边的空白
for(var j = 1; j<5-i;j++){
document.writeln(" ");
}
//1行-1列 2行--2列 3行--3列
for (var k = 0; k<=i;k++) {
document.writeln("口");
}
document.writeln("<br/>");
}
</script>
- v形
<script>
// 5行
for(var i=1;i<6;i++){
//最左边的空白列 1行-0列 2行--1列 3行--2列 4行--3列 5行--4列
for(var j=1;j<i;j++){
document.writeln(' ');
}
// 最左边的小星星
for(var k=1;k<=1;k++){
document.writeln('⭐')
}
//中间的空白列 1--7 2--5 3--3 4--1 5--0
for(var h=1;h<=9-2*i;h++){
document.writeln(' ');
}
//最右边的小星星
for(var l=1;l<=1;l++){
if (i!= 5) {
document.writeln('⭐')
}
}
document.writeln('<br/>');
}
</script>
- x图形
<script>
// 打印x的上半部分
for(var i = 0;i<=5;i++){
//列前面空格
for(var j=0;j<i;j++){
document.writeln(" ");
}
//列中第一个星星
for(var k=0;k<=0;k++){
document.writeln("⭐");
}
//每列两个星星中间的列空格
for(var h=0;h<=10-(i+1)*2;h++){
document.writeln(" ");
}
//列中第二个星星
for( var k=0; k <= 0;k++){
if(i!=5){
//在v的底部只要一个星星.所以要去掉一个
document.writeln("⭐");
}
}
document.writeln("<br/>");
}
//x的下半部分
for(var i = 0;i<=5;i++){
//列前面空格
for(var j=0;j<4-i;j++){
document.writeln(" ");
}
//列中第一个星星
for(var k=0;k<=0;k++){
//保证上v下v中⭐的个数相同,则下v左边最后一个⭐要去掉
if(i!=5){
document.writeln("⭐");
}
}
//每列两个星星中间的列空格
for(var h=0;h<=i*2;h++){
document.writeln(" ");
}
//列中第二个星星
for( var k=0; k <= 0;k++){
if(i!=5){
//在v的底部只要一个星星.所以要去掉一个
document.writeln("⭐");
}
}
document.writeln("<br/>");
}
</script>
四.for循环算法题
在接下来的算法题中,我们会接触到两个重要概念:累加器和累乘器
1.计算 1+2+3+4+…+99+100的和
求 1+2+3+4+…+99+100的和,本质就是等差数列求和
等差数列
- 等差数列:如果一个数列从第二项开始,每一项与它前一项的差等同于同一个常数,这个数列就是等差数列
- 如1,2,3,4,5,6…或1,3,5,7,9,…
- 如果我们要计算等差数列的求和,在数学中是有计算公式的,也就是前面讲到的高斯算法:
- 计算等差数列的前n项和:Sn=(n*(a1+an))/2
- a1代表首项,a2代表第二项,an代表第n项
- 在计算机中并没有等差数列的求和公式,我们必须一项一项加起来,就要用到for循环
- 在JS中,我们用累加器来计算
<script>
//创建累加器
var sum=0; //累加器的初始值为0
//遍历1-100的每一个数字,每遍历一个数字,就要把这个数字加到sum中
for(var i=1;i<=100;i++){
sum=sum+i;
}
//输出累加器的值
console.log(sum);
</script>
注意:
- 累加器(变量sum)必须定义在循环外面的前面
- 累加器的初始值必须设置,而且必须设置为0,不会影响累加效果
- 使出最终累加结果时,必须在for循环结束后的外面
- 很多JS大神喜欢将sum这样的变量,书写在for循环的括号中
<script>
//循环开始的时候定义sum,sum就是累加器,初始值为0
//遍历1-100的每一个数字,每遍历一个数字,就要把这个数字加到sum中
for(var i=1,sum=0;i<=100;i++){
sum=sum+i;
}
//输出累加器的值
console.log(sum);
</script>
2.计算10的阶乘
- 一个正整数的阶乘(factorial)是所有小于即等于该数的正整数的积,并且0的阶乘为1
- 自然数n的阶乘写作n!
- 10!=10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
- 在JS中我们使用累乘器来操作
<script>
var n=1;
for(var i=10;i>=1;i--){
n*=i;
}
//循环结束后使用累乘结果
console.log(n); // 3628800
</script>
五.while循环
while表示当的意思,是一种先测试语句,和for循环一样,先测试条件,根据测试条件再判断是否执行循环体中代码
while(测试条件){
//执行语句,代码块
}
var i=1; //循环变量
while(i<10){ // 测试条件
//循环体
console.log(i);
i++;
}
1.while循环注意事项
- while语句事先不指定循环开始,结束的范围,只要测试条件满足,就一直执行循环体
- 所以while循环体内的语句,必须使循环测试条件趋向于不成立,否则会死循环
- while循环没有指定的循环变量,必顺在循环外定义好循环的变量
var i=0; // 定义循环变量
var num=0; // 累加器
while(i<=10){
num+=i;
i++; //更新循环变量
}
2.更适合while的应用场景
while循环更适合,没有定范围的循环,根据结果找条件
2.1,寻找n²大于23450的最小整数
<script>
var n=1;
while(n*n<=23450){
n++;
}
console.log(n); // 154
</script>
2.2.小兔子拔萝卜,第1天拔1个,第2天拔2个,第3天拔3个,…,以此类推,请问小兔子多少天能把500个萝卜拔完?
- 我们把题转换为以下表格,大家发现,这是之前讲过的等差数列的求和
第1天 | 第2天 | 第3天 | 第…天 | 第n-1天 | 第n天 |
---|---|---|---|---|---|
1 | 2 | 3 | … | n-1 | n |
-
当等差数列1,2,3,4…,n-1,n之和第一次>500时,这里的n就是我们要找的n
-
所以我们需要一个累加器来累加所有天数萝卜之和,当累加器的值<500时,就一直累加,加到>500时就不加了.
<script>
var sum=0;// 累加器
var day=1; //记录天数
while(sum<500){
day++;
sum+=day; // 最后一次循环会多加一个1
}
console.log(day-1); // 31
</script>
验证:通过等差数列求和公式:(首项+末项)*项数 / 2 =和
- 计算1+2+3+4+…+32的和
- (1+32)*32/2=528
六.do while循环
- do while 循环是一种后测试循环语句,这一点和while和for都不一样
- for循环和while循环每次都是先测试条件是否满足,然后再执行循环体
- do while循环是先执行循环,然后测试条件是否满足
do {
// 循环体
} while(循环执行条件)
- 循环体一定会至少执行一次,然后再检测循环执行条件是否为true,决定是否继续执行循环体
- do while 循环将循环条件写到了循环体的后面
// do while循环是后判断的循环形式,能至少执行一次循环体
do {
console.log("刘宇宁"); // 刘宇宁
} while(false);
1.更适合 do while 的应用场景
先运行一次代码,如果不符合条件就重做,符合就不做了
其不满足条件是在事情做完之后产生的
1.1随机产生两个1-10之间的整数,但是这两个数之和要等于10
<script>
// 0-10之间的随机数
var a,b;
do {
a = parseInt(Math.random()*10) +1;
b = parseInt(Math.random()*10) +1;
} while(a+b!=10);
console.log(a,b); // 4,6
</script>
随机得到[a,b]区间的整数: parseInt(Math.random()*(b-a+1)) +a
1.2随即移动元素的位置
- 在做游戏开发和动画的时候,我们想随机生成两个数a和b,作为元素在x,y轴方向的移动距离
- 要求a和b的值均在[-10,10]区间随机取整数
- 但a和b不能同时为0
<script>
var x,y;
do {
x = parseInt(Math.random()*21) -10;
y = parseInt(Math.random()*21) -10;
} while(x==0 && y==0);
console.log(x,y);
</script>
七.break,continue,label语句
- break和continue语句为执行循环代码提供了更严格的控制手段
1.break语句
break语句用于立即退出当前循环,它只能用在循环语句中,如for循环和while循环都可以
<script>
for(var i=0;i<10;i++){
console.log(i);
if(i == 5){
break;
}
}
// 输出0,1,2,3,4,5
//当执行到i==5时,遇到break,就会退出整个循环语句
</script>
- break在for嵌套中,他只会退出它所在的那个for循环语句,然后继续执行当前for循环外的for循环体中的语句
<script>
for(i=0;i<4;i++){
for(var j=0;j<4;j++){
if (j==3){
break; //每次执行到j==3时,就会退出当前for循环,继续执行当前for循环外的for循环体中的语句
}
console.log(i+"-"+j);
}
console.log('j'+j); //break退出for时,会从这里开始执行下一次的外层for循环
}
</script>
2.continue语句
- continue语句用于跳过循环中的一个迭代,并继续执行循环中的下一个迭代
- continue语句经常配合for循环使用
<script>
for(var i=0;i<10;i++){
if(i == 5){
continue;
}
console.log(i);
}
</script>
- continue语句在for嵌套中,也是跳过循环中的一个迭代,并继续执行循环中的下一个迭代
<script>
for(i=0;i<4;i++){
for(var j=0;j<4;j++){
if (j==2){
continue;
}
console.log(i+"-"+j);
}
}
</script>
3.label语句
- 我们上面讲过,不管是continue还是break,它最多能退出的也就是当前的for循环,如果我想退出最外层for循环,那就可以借助这里的label
- 在实际开发应用中不多,了解即可
label:statement
- label表示标签名,这个名字是可以自定义的标识符
- statement表示代码块
- label标签名和statement代码块之间使用英文状态下的冒号分隔
- label标签一般都是与for循环语句等循环语句配合使用,同时是由break和continue语句引用的
label标签与continue语句相结合
- 两者结合,表示退出到label标记位置,继续从label标签标识的for循环开始执行下一次循环
<script>
//outer就是label标签,用来标识第一个for循环语句,其名字outer可以自定义,不一定是outer
outer:for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
if (j==2){
continue outer;
}
console.log(i+"-"+j);
}
console.log(i+"-"+j); // continue outer退出时,不会执行这个代码
}
</script>
这里要特别注意区分和break的区别,break是退出当前for循环,会从for循环的外层循环语句体开始执行.
<script>
//outer就是label标签,用来标识第一个for循环语句,其名字outer可以自定义,不一定是outer
outer:for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
if (j==2){
break;
}
console.log(i+"-"+j);
}
console.log(i+"-"+j); // break退出时,会执行这个代码
}
</script>
4.关于break,continue,label语句总结`
break | break语句用于立即退出当前循环,它只能用在循环语句中,如for循环和while循环都可以 |
---|---|
语句 | 描述 |
continue | continue语句用于跳过循环中的一个迭代,并继续执行循环中的下一个迭代 |
label | 与break配合:表示立即退出到label标签标识后的for循环,不再执行 与continue配合:表示退出到label标签标记位置,继续从label标签标识后的for循环开始执行下一次循环 |
八.循环语句总结
循环类型 | 语法 | 使用场景 |
---|---|---|
for循环 | for(语句1;语句2;语句3){ 被执行的代码块 } | 循环次数都是固定的,知道明确的循环范围 |
while循环 | while(测试条件){ //执行语句,代码块 } | 循环次数不定,更适合根据结果找条件 |
do while循环 | do { // 循环体 } while(循环执行条件) | 先运行一次代码,如果不符合条件重做,符合就不做了. 其不满足条件是在事情做完后产生的 |
九.重难点总结
1.Javascript 流程控制语句和算法
-
分支结构语句
- if语句
- switch语句
-
循环节构的语句
- for 语句
- while 语句
- do while 语句
-
其他语句
- break 退出当前循环
- continue语句用于跳过当前循环中的一个迭代,并继续执行循环中的下一个迭代
- label给语句加标签,常和for嵌套循环一起使用
2.if多分支语句的执行机理,for循环的执行机理
- if执行机理
- for循环的执行机理
3.for和while,do while 循环各有什么应用场景?
循环语句 | 应用场景 |
---|---|
for循环 | 循环次数都是固定的,知道明确的循环范围 |
while循环 | 循环次数不定,更适合根据结果找条件 |
do while循环 | 先运行一次代码,如果不符合条件重做,符合就不做了. 其不满足条件是在事情做完后产生的 |
4.for循环打印图形规律
- 外层for循环控制行
- 内层for循环控制列
5.break,continue,label语句的用法
break | break语句用于立即退出当前循环,它只能用在循环语句中,如for循环和while循环都可以 |
---|---|
语句 | 描述 |
continue | continue语句用于跳过循环中的一个迭代,并继续执行循环中的下一个迭代 |
label | 与break配合:表示立即退出到label标签标识后的for循环,不再执行 与continue配合:表示退出到label标签标记位置,继续从label标签标识后的for循环开始执行下一次循环 |
难点内容:
1.for和while,do while 循环各有什么应用场景?
2.for循环的应用案例
十.作业
下面的代码运行结果是什么?
<script>
var str="icoding123";
var num=parseInt(str);
if(num==NaN){
alert(NaN);
} else {
alert(str);
}
</script>
<script>
var a=1;
var b=0;
var str1='';
var str2=false;
if (a || b || str1){
alert(a+b+str1);
}
if(a && b && !str2){
alert(!str2);
}
if(a && !str1 && !str2){
alert(!str1);
}
</script>
2.完整课程中讲到的所有案例
十一.算法题
接下来,我们学习算法,算法是大厂面试必考题,了解算法是非常有必要的,首先来了解什么是算法?
1.什么是算法?
这里我们从算法的一个小故事开始切入
有一个熊孩子十分淘气,一次数学课上,老师为了让他们安静下来,出了一道很难的题,让他们一个小时之内算出1+2+3+4+5+…+99+100的得数.
作为正常思维,我们会如何计算?
- 1+2=3
- 3+3=6
- 6+4=10
- …
结果这个孩子只用了20分钟算出,因为他想到了用(1+100)+(2+99)+(3+98)…+(60+51)…一共50个101,所以50*101就是1+2+3+4+5+…+99+100的得数.
这个孩子名为高斯,后来人们将这种简便算法称为高斯算法
什么是算法?
- 在数学领域中,算法是用来解决某一类问题的公式和思想
- 而在计算机领域中,他本质是一系列程序指令,用来解决特定的运算和逻辑问题
- 在计算机中,算法就是把一个问题,拆解为计算机能够一步一步执行的步骤
1.累加器和累乘器
1.1累加器
由用户输入数字n,请计算下面算式的值
- 首先来找规律
- 第一项分母从2开始,每一项分子比分母大1
- 所以在for循环遍历时,只需要遍历分母就好,分母为i,分子为i-1
<script>
// 由用户输入数字n,计算3/2+4/3+5/4+...+(n+1)/n 的结果
// 用户输入数字n
var n = Number(prompt("请用户输入数字n"));
// 累加器
var sum=0;
// 遍历分母就好,分母为i,分子为i-1
for(var i=2;i<=n;i++){
sum +=(i+1)/i;
}
alert(sum.toFixed(2)); //这里特别注意小数的处理
</script>
1.2 累乘器
由用户输入数字n,计算n的阶乘
5的阶乘=5*4*3*2*1
<script>
//计算阶乘
// 用户输入数字n
var n = Number(prompt("请用户输入数字n"));
//累乘器 一定要注意累乘器从1开始,从0开始任何数都为0
var result=1;
//倒着遍历,计算阶乘
for(var i=n;i>=1;i--){
result *=i;
}
//显示结果
alert(result);
</script>
1.3累加器与累乘器的结合
- 圆周率Π可以由下面的莱布尼兹级数公式计算出来,请由用户输入参数n,计算圆周率Π
- 这是大厂经典面试题
通过上面公式,得到圆周率Π=2 * (1+1/3+(1 * 2)/(3 * 5)+(1 * 2 * 3)/(3 * 5 * 7)+(1 *2 * 3 *4)/(3 * 5 * 7 * 9)+…+(1 * 2 * 3 *… * n)/(3 * 5 * … * (2n+1)));
- 第一步:找规律,除去第一项,每一项都等于前一项* n/(n * 2 + 1)
- 这里需要累乘器计算出每一项需要的值
- 然后利用累加器,把每一项加起来
<script>
// 累加器 就是最后的答案
var sum=0;
// 累乘器用来制作每一项,制作出来的这个项,要往累加器中累加
var item = 1;
//让用户输入n
var n = Number(prompt("请用户输入数字n"));
//遍历
for(var i=1;i<=n;i++){
//要先制作项目
item *= i / (2 * i + 1);
console.log(item);
//把每一项往累加器中累加
sum += item;
}
//显示结果
console.log((1 + sum) * 2);
</script>
注意:算法题最难的点在于找到背后的规律和相关的一些通用处理算法的技巧
2.穷举法
穷举法是什么?
- 穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有的情况逐一验证,直到全部情况验证完毕.
- 若某个情况验证符合题目的全部条件,则为本问题的一个解
- 若全部情况验证后都不符合题目的全部条件,则本题无解
- 穷举法也称为无解法
穷举法是一种算法思想,把在条件范围内的所有情况都注意验证
2.1寻找100以内既能被3整除,也能被5整除的数字
计算机不会找规律和逻辑推理,它最大的优势就是强大的计算能力
<script>
//寻找100以内既能被3整除,也能被5整除的数字
// 穷举法 从1开始实验
for(var i=1;i<=100;i++){
if(i%3==0 && i%5==0){
console.log(i); // 15 30 45 60 75 90
}
}
</script>
```
1.2 累乘器
由用户输入数字n,计算n的阶乘
5的阶乘=5*4*3*2*1
<script>
//计算阶乘
// 用户输入数字n
var n = Number(prompt("请用户输入数字n"));
//累乘器 一定要注意累乘器从1开始,从0开始任何数都为0
var result=1;
//倒着遍历,计算阶乘
for(var i=n;i>=1;i--){
result *=i;
}
//显示结果
alert(result);
</script>
1.3累加器与累乘器的结合
- 圆周率Π可以由下面的莱布尼兹级数公式计算出来,请由用户输入参数n,计算圆周率Π
- 这是大厂经典面试题
[外链图片转存中…(img-iHlr75oR-1691581043572)]
通过上面公式,得到圆周率Π=2 * (1+1/3+(1 * 2)/(3 * 5)+(1 * 2 * 3)/(3 * 5 * 7)+(1 *2 * 3 *4)/(3 * 5 * 7 * 9)+…+(1 * 2 * 3 *… * n)/(3 * 5 * … * (2n+1)));
- 第一步:找规律,除去第一项,每一项都等于前一项* n/(n * 2 + 1)
- 这里需要累乘器计算出每一项需要的值
- 然后利用累加器,把每一项加起来
<script>
// 累加器 就是最后的答案
var sum=0;
// 累乘器用来制作每一项,制作出来的这个项,要往累加器中累加
var item = 1;
//让用户输入n
var n = Number(prompt("请用户输入数字n"));
//遍历
for(var i=1;i<=n;i++){
//要先制作项目
item *= i / (2 * i + 1);
console.log(item);
//把每一项往累加器中累加
sum += item;
}
//显示结果
console.log((1 + sum) * 2);
</script>
注意:算法题最难的点在于找到背后的规律和相关的一些通用处理算法的技巧
2.穷举法
穷举法是什么?
- 穷举法的基本思想是根据题目的部分条件确定答案的大致范围,并在此范围内对所有的情况逐一验证,直到全部情况验证完毕.
- 若某个情况验证符合题目的全部条件,则为本问题的一个解
- 若全部情况验证后都不符合题目的全部条件,则本题无解
- 穷举法也称为无解法
穷举法是一种算法思想,把在条件范围内的所有情况都注意验证
2.1寻找100以内既能被3整除,也能被5整除的数字
计算机不会找规律和逻辑推理,它最大的优势就是强大的计算能力
<script>
//寻找100以内既能被3整除,也能被5整除的数字
// 穷举法 从1开始实验
for(var i=1;i<=100;i++){
if(i%3==0 && i%5==0){
console.log(i); // 15 30 45 60 75 90
}
}
</script>