JavaScript 基础之分支结构

345 阅读11分钟

本章目标

  • 掌握 if 语句的使用
  • 掌握 switch 语句的使用
  • 掌握三元表达式的使用

本章任务

  • 完成 if/switch 语句中的案例
  • 完成仿 siri 项目中用户选择功能部分

表达式和语句

表达式

一个表达式可以产生一个值,有可能是运算、函数调用、有可能是字面量。表达式可以放在任何需要值的地方。

let a = (5 + 6);

语句

语句可以理解为一个行为,循环语句和判断语句就是典型的语句。一个程序有很多个语句组成,一般情况下;分割一个一个的语句。

console.log(12); // 行为就是输出了一个12在控制台 alert('Hello'); // 行为就是弹出了个提示框

流程控制

我们想要实现一个复杂的效果,只简单的代码是肯定不行的,还要实现代码执行过程的控制——流程控制。

程序的三种基本结构:

  1. 顺序结构
  2. 分支结构
  3. 循环结构

顺序结构

从上到下执行的代码就是顺序结构

程序默认就是由上到下顺序执行的

分支结构

根据不同的情况,执行对应代码

循环结构

循环结构:重复做一件事情

分支结构

我们在日常生活中,有很多事情是需要做判断的,比如说,去服装城买衣服,你看中一件衣服,老板要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); }

案例

  1. 求两个数最大值(练习 if-else结构)
  2. 求三个数最大值(练习if-else的嵌套)
  3. 计算每月的天数
    1. 1,3,5,7,8,10,12月份,有31天
    2. 4,6,9,11月份,有30天
    1. 2月份,如果闰年29 平年28
  4. 输入年份,判断是否是闰年
    • 年份能被4整除但是不能被100整除
    • 年份能被400整除
  1. 判断水仙花数

设置断点查看代码的执行过程

断点:让代码执行的时候暂停的位置,可以查看执行到当前位置后,代码中当前状态的变量的值。

设置好断点后 F5 刷新浏览器,让代码执行到断点的位置。

  • F11 代码单步执行
  • 鼠标放到某个变量,可以查看当前变量的值

switch 语句

switch 语句主要用于多个固定值之间的判断。等值判断中比较常用,计算每月的天数如果用switch语句来实现会更方便。我们的仿 siri 项目中,判断用户输入的编号和内容就使用的 switch 语句。

  • 语法

switch (变量) { case 值1: 执行的代码块 break; case 值2: 执行的代码块 break; 。。。 default: 执行代码块 }

    1. break 表示当前分支执行后就结束 switch 的运行,后续代码不再运行
    2. default 可以理解为判断语句中的 else
    1. 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. 1,3,5,7,8,10,12月份,有31天
    2. 4,6,9,11月份,有30天
    1. 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,1231// 4,6,9,1130// 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或者总和,打印用户选择的相应计算方式