本章目标
- 掌握 if 语句的使用
- 掌握 switch 语句的使用
- 掌握三元表达式的使用
本章任务
- 完成 if/switch 语句中的案例
- 完成仿 siri 项目中用户选择功能部分
表达式和语句
表达式
一个表达式可以产生一个值,有可能是运算、函数调用、有可能是字面量。表达式可以放在任何需要值的地方。
let a = (5 + 6);
语句
语句可以理解为一个行为,循环语句和判断语句就是典型的语句。一个程序有很多个语句组成,一般情况下;分割一个一个的语句。
console.log(12); // 行为就是输出了一个12在控制台 alert('Hello'); // 行为就是弹出了个提示框
流程控制
我们想要实现一个复杂的效果,只简单的代码是肯定不行的,还要实现代码执行过程的控制——流程控制。
程序的三种基本结构:
- 顺序结构
- 分支结构
- 循环结构
顺序结构
从上到下执行的代码就是顺序结构
程序默认就是由上到下顺序执行的
分支结构
根据不同的情况,执行对应代码
循环结构
循环结构:重复做一件事情
分支结构
我们在日常生活中,有很多事情是需要做判断的,比如说,去服装城买衣服,你看中一件衣服,老板要300元,你立马就会想,这个价格是否贵了,判断的结果只有两种可能,一是贵,二是不贵,贵了你就不买了,不贵你就买了。再比如去网吧,网管也要判断你是否满18岁,结果也只有两种,是和否,是就上网,不是就看别人上网,再比如,学校根据考试成绩对每个人进行评级,如果成绩大于60就合格,否则就不合格,如果成绩大于90,就优秀等等。
本章学习完毕后我们就可以在代码中实现上述的逻辑判断功能。
判断也会有很多种,比如:
- 考试成绩大于等于60,及格
- 考试成绩大于等于60,及格,否则,不及格
- 考试成绩如果大于等于60及格,60到70之间成绩可以,70到80之间成绩中等,如果大于80并且小于90,良好,如果大于90,优秀
根据上述几种情况,我们把判断分为三种,根据结果只做一个件事情的,叫单分支,做两件事情的,叫做双分支,做多件事情的,叫多分支。
单分支
单分支:满足一个指定条件,执行指定的代码块。
- 语法
if (条件表达式) { 当条件表达式的结果为 true 的时候要执行的代码 }
- 示例
用户输出成绩,转换成浮点数,判断成绩是否及格(大于60分)
let score = prompt('请输入你的成绩'); score = parseFloat(score); if (score >= 60) { console.log('及格') }
双分支
双分支:满足指定条件,执行指定的代码块;不满足条件,执行另一个代码块。
- 语法
if (条件表达式) { 当条件表达式的结果是 true 时执行的代码 } else { 当条件表达式的结果是 false 时执行的代码 }
- 示例
用户输入成绩,如果大于60分输出及格,否则输出不结构
let score = prompt('请输入你的成绩');
score = parseFloat(score);
if (score >= 60) {
console.log('及格,买糖吃');
} else {
console.log('不及格,打pp');
}
多分支
多分支:多个条件的判断,如果满足其中一个条件只执行对应的一个代码块。
- 语法
if (条件表达式1) { 当条件表达式1的结果为true的时候,要执行的代码 } else if (条件表达式2) { 当条件表达式2的结果为true的时候,要执行的代码 } else if (条件表达式3) { 当条件表达式3的结果为true的时候,要执行的代码 } else { }
-
- 多分支可以有若干个 else if,else 根据需要可以有也可以没有
- 当多个条件都满足时,只会执行第一个满足条件的表达式对应的代码块(代码是从上往下依次执行的)
-
示例
用户输入成绩,判断输入的是否是数字如果不是提示用户输出正确的成绩。
-
- 成绩在[0, 60)之间,输出差
- 成绩在[60, 70)之间,输出可
- 成绩在[70, 80)之间,输出中
- 成绩在[80, 90)之间,输出良
- 成绩在[90, 100)之间,输出优
- 其它值输出,成绩范围不正确
let score = parseFloat(prompt('请输入考试成绩:'));
if (isNaN(score)) {
console.log('请输入正确的成绩');
} else {
if (score >= 0 && score < 60) {
console.log('差')
} else if (score >= 60 && score < 70) {
console.log('可');
} else if (score >= 70 && score < 80) {
console.log('中');
} else if (score >= 80 && score < 90) {
console.log('良');
} else if (score >= 90 && score <= 100) {
console.log('优');
} else {
console.log('输入的成绩范围不正确');
}
}
根据多分支结构的特点,我们可以对代码进行优化,当有一个条件满足,不再判断其它条件。所以这里的判断成绩可以从大到下判断,代码如下:
- 成绩>=90分,输出优
- 成绩>=80分,输出良
- 成绩>=70分,输出中
- 成绩>=60分,输出可
- 成绩<60分,输出差
let score = parseFloat(prompt('请输入考试成绩:'));
if (isNaN(score)) {
alert('请输入正确的成绩');
} else {
if (score > 100 || score < 0) {
console.log('输入的成绩范围不正确');
} else if (score >= 90) {
console.log('优');
} else if (score >= 80) {
console.log('良');
} else if (score >= 70) {
console.log('中');
} else if (score >= 60) {
console.log('可');
} else if (score >= 0) {
console.log('差');
}
}
if 语句其它
if 语句的简写
如果 if 语句的大括号(代码块) 中只包含一条语句,大括号可以省略,例如:
let score = prompt('请输入你的成绩'); score = parseFloat(score); if (score >= 60) console.log('及格,买糖吃'); else console.log('不及格,打pp');
注意: 虽然上面代码可以正常执行,但是始终不推荐这样写代码,这样的话会让代码结构不清晰。
if 语句的隐式转换
if 语句的条件表达式的结果是布尔值,所以可以将布尔值当做条件放入 if 的小括号中
if (true) { console.log('真的'); } else { console.log('假的'); }
如果将非布尔值的表达式或数据放入小括号中,会发生隐式类型转换,转换的规则如下:
- 0、''(空字符串)、null、undefined、NaN 会转换成 false,其它值都会转换成 true。
if (2) { console.log(2); }
案例
- 求两个数最大值(练习 if-else结构)
- 求三个数最大值(练习if-else的嵌套)
- 计算每月的天数
-
- 1,3,5,7,8,10,12月份,有31天
- 4,6,9,11月份,有30天
-
- 2月份,如果闰年29 平年28
- 输入年份,判断是否是闰年
-
- 年份能被4整除但是不能被100整除
- 年份能被400整除
- 判断水仙花数
设置断点查看代码的执行过程
断点:让代码执行的时候暂停的位置,可以查看执行到当前位置后,代码中当前状态的变量的值。
设置好断点后 F5 刷新浏览器,让代码执行到断点的位置。
- F11 代码单步执行
- 鼠标放到某个变量,可以查看当前变量的值
switch 语句
switch 语句主要用于多个固定值之间的判断。等值判断中比较常用,计算每月的天数如果用switch语句来实现会更方便。我们的仿 siri 项目中,判断用户输入的编号和内容就使用的 switch 语句。
- 语法
switch (变量) { case 值1: 执行的代码块 break; case 值2: 执行的代码块 break; 。。。 default: 执行代码块 }
-
- break 表示当前分支执行后就结束 switch 的运行,后续代码不再运行
- default 可以理解为判断语句中的 else
-
- case 理解为 if 来判断这个变量是否等于某个值(注意这里不会发生隐式类型转换),等值判断用的是 ===
- 示例
用户输入1-7之间的一个数字,返回对应的星期。
let day = Number(prompt('请输入一个1~7之间数字:'));
if (isNaN(day)) {
console.log('输入的值不合法');
} else {
switch (day) {
case 1:
console.log('星期一');
break;
case 2:
console.log('星期二');
break;
case 3:
console.log('星期三');
break;
case 4:
console.log('星期四');
break;
case 5:
console.log('星期五');
break;
case 6:
console.log('星期六');
break;
case 7:
console.log('星期日');
break;
default:
console.log('输入错误');
break;
}
}
switch 语句中的 break 可以省略,如果省略会发生什么?我们可以把上例中的 break 删除,然后测试下运行的结果。
let day = Number(prompt('请输入一个1~7之间数字:'));
if (isNaN(day)) {
console.log('输入的值不合法');
} else {
switch (day) {
case 1:
console.log('星期一');
case 2:
console.log('星期二');
case 3:
console.log('星期三');
case 4:
console.log('星期四');
……
}
}
在浏览器中运行,然后输入1,你会发现处理打印星期一,意外剩下的 case 块,包括 default 都执行的。这就是我们常说的 switch 的穿透效果。
你可能会说这样不好,以后不要省略 break。其实不然,在上述的案例中 break 省略后计算的结果就不正确了。但是省略 break 有其用途。
我们使用 switch 语句重新来实现计算每月的天数案例,代码如下:
-
- 1,3,5,7,8,10,12月份,有31天
- 4,6,9,11月份,有30天
-
- 2月份,如果闰年29 平年28
let month = parseInt(prompt('请输入月份'));
if (isNaN(month) || month <= 0 || month > 12) {
console.log('输入错误');
} else {
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log('这个月有31天');
break;
case 4:
case 6:
case 9:
case 11:
console.log('这个月有30天');
break;
case 2:
console.log('这个月有29天或28天');
break;
}
}
通过这个案例你会发现省略 break 有他的特定使用场景,未来在使用 switch 语句的时候要尤其要留心 break 的使用。
总结: if 语句和 switch 语句都是条件判断的语句,多数情况下我们会使用 if 语句,但是等值的条件判断可以用 switch 语句,结构更清晰。
扩展: 虽然 switch 是等值的条件比较,但是我们也可以用一些小技巧,把范围比较转换成等值比较。
下面我们就使用 switch 语句重新来完成之前的成绩转换案例。
-
成绩>=90分,输出优
-
成绩>=80分,输出良
-
成绩>=70分,输出中
-
成绩>=60分,输出可
-
成绩<60分,输出差
我们可以把上面的关系转换成等值比较的关系,首先让成绩/10并且取整,这个时候关系可以转换为如下:
-
成绩===10分,输出优
-
成绩===9分,输出优
-
成绩===8分,输出良
-
成绩===7分,输出中
-
成绩===6分,输出可
-
其它,输出差
let score = parseFloat(prompt('请输入考试成绩:'));
if (isNaN(score) || score < 0 || score > 100) {
console.log('请输入正确的成绩');
} else {
score = parseInt(score / 10);
switch (score) {
case 10:
case 9:
console.log('优');
break;
case 8:
console.log('良');
break;
case 7:
console.log('中');
break;
case 6:
console.log('可');
break;
default:
console.log('差');
break;
}
}
三元表达式
三元表达式是 if-else 结构的简写形式
- 语法:
条件表达式 ? 条件成立返回的结果或者执行的代码 : 条件不成立返回的结果或者执行的代码
- 示例
求两个数的最大值
let num1 = 10; let num2 = 20; let max = num1 > num2 ? num1 : num2; console.log(max)
判断条件后也可以执行执行一个语句
num1 > num2 ? console.log(num1) : console.log(num2);
案例参考代码
- 求两个数最大值(练习 if-else结构)
let num1 = parseInt(prompt('请输入第一个数'));
let num2 = parseInt(prompt('请输入第二个数'));
if (num1 > num2) {
console.log('最大数为:' + num1)
} else {
console.log('最大数为:' + num2)
}
- 求三个数最大值(练习if-else的嵌套)
let num1 = parseInt(prompt('请输入第一个数'));
let num2 = parseInt(prompt('请输入第二个数'));
let num3 = parseInt(prompt('请输入第三个数'));
if (num1 > num2) {
if (num1 > num3) {
console.log('最大数为' + num1);
} else {
console.log('最大数为' + num3);
}
} else {
if (num2 > num3) {
console.log('最大数为' + num2);
} else {
console.log('最大数为' + num3);
}
}
- 计算每月的天数
let month = parseInt(prompt('请输入月份'));
// 1,3,5,7,8,10,12 有31天
// 4,6,9,11 有30天
// 2 如果闰年 29 平年 28
if (month < 1 || month > 12) {
console.log('输入的月份不正确');
}
if (month === 4 || month === 6 || month === 9 || month === 11) {
console.log(30);
} else if (month === 2) {
console.log('平年28天,闰年29天');
} else {
console.log(31);
}
- 输入年份,判断是否是闰年
-
- 年份能被4整除但是不能被100整除
- 年份能被400整除
let year = parseInt(prompt('请输入年份'));
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
console.log('闰年');
} else {
console.log('平年');
}
- 判断水仙花数
-
- 是指一个三位数其各位数字的立方和等于该数本身,例如153是“水仙花数”,因为:153 = 13 + 53 + 33。
let num = parseInt(prompt('请输入一个三位数字'));
let bai = parseInt(num / 100);
let shi = parseInt(num % 100 / 10);
let ge = parseInt(num % 10);
if (num === bai * bai * bai + shi * shi * shi + ge * ge * ge) {
console.log('是水仙花数');
} else {
console.log('不是水仙花数');
}
作业
使用本章所学的 if/switch 语句完成仿 siri 项目中的判断用户输入选项的功能:
- 提示用户输入
- 根据用户的输入,例如:1或者总和,打印用户选择的相应计算方式