Skip to content

07 流程控制语句

Xmind

flow control statement xmind

程序三大流程控制语句

  • 以前我们写的代码,写几句就从上往下执行几句,这种叫顺序结构
  • 有的时候要根据条件选择执行代码,这种就叫分支结构
  • 某段代码被重复执行,就叫循环结构

flow control statement

表达式和语句

  1. 表达式和语句的区别
    因为表达式可被求值,所以它可以写在赋值语句的右侧。
    而语句不一定有值,所以比如 alert()forbreak 等语句就不能被用于赋值。
  2. 表达式是一种计算值的代码片段,而语句是一组指示计算机执行某个操作的代码。
解释举例
表达式可以被求值的代码,并将其计算出一个结果1 + 2num++
语句一段可以执行的代码,是一个行为,例如分支语句和循环语句ifforalert()break
  • 表达式是一段可以求值的代码片段,它可以返回一个结果。

    js
    let a = 10;
    let b = 20;
    let c = a + b; // 这里 c 是一个表达式,其值为 30
  • 语句是一组执行某个操作的代码。语句并不返回一个值。

    js
    // if...else 语句不返回任何值。它只会根据条件执行相应的代码块
    if (a > b) {
      console.log("a 大于 b");
    } else {
      console.log("a 小于或等于 b");
    }
    
    // 赋值语句也是一种语句
    let a = 10;

总结

表达式是一种计算值的代码片段,而语句是一组指示计算机执行某个操作的代码。

分支语句

分支语句可以根据条件判定真假,来选择性的执行想要的代码

分支语句包含:

  1. if 分支语句(重点)
  2. 三元运算符
  3. switch 语句

if 分支语句

javascript
if (条件表达式) {
  // 满足条件要执行的语句
}
  • 小括号内的条件结果是布尔值,为 true 时,进入大括号里执行代码;为 false,则不执行大括号里面代码

  • 小括号内的结果若不是布尔类型时,会发生类型转换为布尔值,类似 Boolean()

  • 如果大括号只有一个语句,大括号可以省略,但是,俺们不提倡这么做~

if 语句案例练习

需求:用户输入高考成绩,如果分数大于 700,则提示恭喜考入黑马程序员。

js
// 1. 用户输入
let score = +prompt("请输入成绩");
// 2. 进行判断输出
if (score >= 700) {
  alert("恭喜考入黑马程序员");
}

if 双分支语句

如果有两个条件的时候,可以使用 if…else… 双分支语句

javascript
if (条件表达式) {
  // 满足条件要执行的语句
} else {
  // 不满足条件要执行的语句
}
判断用户登录案例

需求:用户输入,用户名:pink,密码:123456,则提示登录成功,否则提示登录失败

js
// 1. 用户输入
let uname = prompt("请输入用户名:");
let pwd = prompt("请输入密码:");
// 2. 判断输出
if (uname === "pink" && pwd === "123456") {
  alert("恭喜登录成功");
} else {
  alert("用户名或者密码错误");
}
判断闰年案例

需求:让用户输入年份,判断这一年是闰年还是平年并弹出对应的警示框

js
let year = prompt("请输入一个年份:");
if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
  alert(year + " 年是闰年!");
} else {
  alert(year + " 年是平年!");
}

if 多分支语句

使用场景:适合于有多个条件的时候

输入成绩案例

需求:根据输入不同的成绩,反馈不同的评价

  • 成绩 90 以上是 优秀
  • 成绩 70 ~ 90 是 良好
  • 成绩是 60 ~ 70 之间是 及格
  • 成绩 60 分以下是 不及格
javascript
// 1. 用户输入
let score = +prompt("请输入成绩:");
// 2. 判断输出
if (score >= 90) {
  alert("成绩优秀,宝贝,你是我的骄傲");
} else if (score >= 70) {
  alert("成绩良好,宝贝,你要加油哦~~");
} else if (score >= 60) {
  alert("成绩及格,宝贝,你很危险~");
} else {
  alert("成绩不及格,宝贝,我不想和你说话,我只想用鞭子和你说话~");
}

三元运算符(三元表达式)

使用场景:一些简单的双分支,可以使用 三元运算符(三元表达式),写起来比 if…else 双分支 更简单

符号?: 配合使用

javascript
条件 ? 表达式 1表达式 2
// 如果条件为真,则执行表达式 1
// 如果条件为假,则执行表达式 2
案例练习 - 判断 2 个数的最大值

需求:用户输入 2 个数,控制台输出最大的值

javascript
let num1 = parseInt(prompt("请输入第一个数:"));
let num2 = parseInt(prompt("请输入第二个数:"));

let max = num1 > num2 ? num1 : num2 > num1 ? num2 : "这两个数相等。";

console.log(max + " 是最大的数。");
案例练习 - 数字补 0 案例

需求:用户输入 1 个数,如果数字小于 10,则前面进行补 0,比如 09 03 等

javascript
let num = parseInt(prompt("请输入一个数:"));

let formattedNum = num < 10 ? "0" + num : num.toString();

console.log(formattedNum);

switch 语句(了解)

使用场景:适合于有多个条件的时候,也属于分支语句,大部分情况下和 if 多分支语句 功能相同

js

switch (表达式) {
  case 1:
    代码 1
    break

  case 2:
    代码 2
    break
  ...
  default:
    代码 n
}

// 找到跟小括号里数据全等的 case 值,并执行里面对应的代码
// 若没有全等 === 的则执行 default 里的代码

注意

  1. switch…case 语句一般用于等值判断,if 适合于区间判断
  2. switch…case 一般需要配合 break 关键字使用 没有 break 会造成 case 穿透
  3. if 多分支语句开发要比 switch 更重要,使用也更多

if 多分支语句和 switch 的区别

  1. 共同点

    • 都能实现多分支选择,多选 1
    • 大部分情况下可以互换
  2. 区别:

    • switch…case 语句通常处理 case 为比较确定值的情况,而 if…else… 语句更加灵活,通常用于范围判断(大于,等于某个范围)。
    • switch 语句进行判断后直接执行到程序的语句,效率更高,而 if…else 语句有几种判断条件,就得判断多少次
    • switch 一定要注意 必须是 === 全等,一定注意 数据类型,同时注意 break 否则会有穿透效果
    • 结论:
      • 当分支比较少时,if…else 语句执行效率高。
      • 当分支比较多时,switch 语句执行效率高,而且结构更清晰。
案例练习 - 简单计算器

需求:用户输入 2 个数字,然后输入 + - * / 任何一个,可以计算结果

javascript
let num1 = parseInt(prompt("请输入第一个数:"));
let num2 = parseInt(prompt("请输入第二个数:"));
let operator = prompt("请输入运算符(+、-、*、/):");

let result;

switch (operator) {
  case "+":
    result = num1 + num2;
    break;
  case "-":
    result = num1 - num2;
    break;
  case "*":
    result = num1 * num2;
    break;
  case "/":
    result = num1 / num2;
    break;
  default:
    alert("输入错误,请重新输入。");
}

if (result !== undefined) {
  console.log(num1 + " " + operator + " " + num2 + " = " + result);
}

循环语句

  1. while 循环的作用是什么?
    在满足条件期间,重复执行某些代码
  2. while 循环三要素是什么?
    • 变量起始值
    • 终止条件(没有终止条件,循环会一直执行,造成死循环)
    • 变量变化量(用自增或者自减)
  3. for 循环和 while 循环有什么区别呢:
    • 当如果明确了循环的次数的时候推荐使用 for 循环
    • 当不明确循环的次数的时候推荐使用 while 循环

while 循环

while : 在 …. 期间,所以 while 循环 就是在满足条件期间,重复执行某些代码。

javascript
while (条件表达式) {
  // 循环体
}

// 跟 if 语句很像,都要满足小括号里的条件为 true 才会进入循环体执行代码
// while 大括号里代码执行完毕后不会跳出,而是继续回到小括号里判断条件是否满足,若满足又执行大括号里的代码,然后再回到小括号判断条件,直到括号内条件不满足,即跳出
javascript
// while 循环:重复执行代码

// 1. 需求:利用循环重复打印 3 次 '月薪过万不是梦,毕业时候见英雄'
let i = 1;
while (i <= 3) {
  document.write("月薪过万不是梦,毕业时候见英雄~<br>");
  i++; // 这里千万不要忘了变量自增否则造成死循环
}

while 循环三要素

1.初始值(经常用变量)let i = 1

2.终止条件 while (i <= 3)

3.变量的变化量 i++

js
// 1. 变量的起始值
let end = +prompt("请输入次数:");
let i = 1;
// 2. 终止条件
while (i <= end) {
  document.write("我要循环三次 <br>");
  // 3. 变量的变化量
  i++;
}
案例练习 - 在页面中打印输出 10 句 " 月薪过万 "

需求:使用 while 循环,页面中打印,可以添加换行效果

js
let count = 1;
while (count <= 10) {
  console.log("月薪过万");
  count++;
}
案例练习 - 页面输出 1-100

核心思路:利用 i ,因为正好和 数字对应

js
var i = 1;
while (i <= 100) {
  console.log(i);
  i++;
}
案例练习 - 计算从 1 加到 100 的总和并输出

核心思路:

  • 声明累加和的变量 sum
  • 每次把 i 加到 sum 里面
js
var i = 1;
var sum = 0;
while (i <= 100) {
  sum += i;
  i++;
}
console.log(sum);
案例练习 - 计算 1-100 之间的所有偶数和

核心思路:

  • 声明累加和的变量 sum
  • 首先利用 if 语句把 i 里面是偶数筛选出来
  • 把 筛选的 i 加到 sum 里面
js
var i = 1;
var sum = 0;
while (i <= 100) {
  if (i % 2 === 0) {
    sum += i;
  }
  i++;
}
console.log(sum);

中止循环

  • break 中止整个循环,一般用于结果已经得到,后续的循环不需要的时候可以使用(提高效率)

  • continue 中止本次循环,一般用于排除或者跳过某一个选项的时候

案例练习 - 页面弹框

需求:页面弹出对话框,' 你爱我吗 ',如果输入 ' 爱 ',则结束,否则一直弹出对话框

  • 循环条件永远为真,一直弹出对话框
  • 循环的时候,重新让用户输入
  • 如果用户输入的是:爱,则退出循环(break)
js
// var answer = '';
// while (answer !== '爱') {
//   answer = window.prompt('你爱我吗?');
// }

while (true) {
  var answer = window.prompt("你爱我吗?");

  if (answer === "爱") {
    break;
  }
}

无限循环

1.while(true) 来构造 " 无限 " 循环,需要使用 break 退出循环。(常用)

2.for(;;) 也可以来构造 " 无限 " 循环,同样需要使用 break 退出循环。

js
// 无限循环
// 需求:页面会一直弹窗询问你爱我吗?
// (1). 如果用户输入的是 '爱',则退出弹窗
// (2). 否则一直弹窗询问

// 1. while(true) 无限循环
// while (true) {
//   let love = prompt('你爱我吗?')
//   if (love === '爱') {
//     break
//   }
// }

// 2. for(;;) 无限循环
for (;;) {
  let love = prompt("你爱我吗?");
  if (love === "爱") {
    break;
  }
}
综合案例 - ATM 存取款机

ATM 存取款机 (codepen.io)

图片 8

分析:

  • 提示输入框写到循环里面(无限循环)
  • 用户输入 4 则退出循环 break
  • 提前准备一个金额预先存储一个数额 money
  • 根据输入不同的值,做不同的操作
    • 取钱则是减法操作,存钱则是加法操作,查看余额则是直接显示金额
    • 可以使用 if … else if … else 多分支 来执行不同的操作
js
let balance = 1000;

while (true) {
  let action = +prompt("请选择要执行的操作:\n\n1. 存钱\n2. 取钱\n3. 查看余额\n4. 退出");

  if (action === 4) {
    break;
  }

  switch (action) {
    case 1:
      var deposit = parseInt(window.prompt("请输入存款金额:"));
      if (!isNaN(deposit)) {
        balance += deposit;
        alert("您已成功存入" + deposit + "元。\n当前余额为" + balance + "元。");
      }
      break;

    case 2:
      var withdrawal = parseInt(window.prompt("请输入取款金额:"));
      if (!isNaN(withdrawal) && withdrawal <= balance) {
        balance -= withdrawal;
        alert("您已成功取出" + withdrawal + "元。\n当前余额为" + balance + "元。");
      } else {
        alert("余额不足或输入无效,请重新输入。");
      }
      break;

    case 3:
      alert("当前余额为" + balance + "元。");
      break;

    default:
      alert("输入无效,请重新输入。");
      break;
  }
}

for 循环

for 是 JavaScript 提供的另一种循环控制的话句,它和 while 只是语法上存在差异。

js
for (初始化表达式; 循环条件; 循环迭代器) {
  // 循环体代码
}

// 初始化表达式:在循环开始前运行的语句,通常用来初始化循环变量。
// 循环条件:在每次循环开始前检查的条件,如果条件为 true,继续循环;否则退出循环。
// 循环迭代器:在每次循环结束时运行的语句,通常用来更新循环变量。
// 循环体代码:在每次循环开始前运行的语句块。

for 语句的基本使用

  1. 实现循环的 3 要素

    js
    // 1. 语法格式
    // for(起始值; 终止条件; 变化量) {
    //   // 要重复执行的代码
    // }
    
    // 2. 示例:在网页中输入标题标签
    // 起始值为 1
    // 变化量 i++
    // 终止条件 i <= 6
    for (let i = 1; i <= 6; i++) {
      document.write(`<h${i}>循环控制,即重复执行<h${i}>`);
    }
  2. 变化量和死循环,for 循环和 while 一样,如果不合理设置增量和终止条件,便会产生死循环。

  3. 跳出和终止循环

    • continue 退出本次循环,一般用于排除或者跳过某一个选项的时候,可以使用 continue
    • break 退出整个 for 循环,一般用于结果已经得到,后续的循环不需要的时候可以使用
    js
    // 1. continue
    for (let i = 1; i <= 5; i++) {
      if (i === 3) {
        continue; // 结束本次循环,继续下一次循环
      }
      console.log(i);
    }
    // 2. break
    for (let i = 1; i <= 5; i++) {
      if (i === 3) {
        break; // 退出结束整个循环
      }
      console.log(i);
    }

    结论

    • JavaScript 提供了多种语句来实现循环控制,但无论使用哪种语句都离不开循环的 3 个特征,即起始值、变化量、终止条件,做为初学者应着重体会这 3 个特征,不必过多纠结三种语句的区别。
    • 起始值、变化量、终止条件,由开发者根据逻辑需要进行设计,规避死循环的发生。
    • 当如果明确了循环的次数的时候推荐使用 for 循环,当不明确循环的次数的时候推荐使用 while 循环

    注意

    for 的语法结构更简洁,故 for 循环的使用频次会更多。

案例练习 - 循环练习

需求:利用 for 循环输出 1~100 岁

javascript
for (let i = 1; i <= 100; i++) {
  console.log(i + "岁");
}

需求:求 1-100 之间所有的偶数和

javascript
let sum = 0;
for (let i = 1; i <= 100; i++) {
  if (i % 2 === 0) {
    sum += i;
  }
}
console.log("1-100 之间所有的偶数和为:" + sum);

需求:页面中打印 5 个小星星

javascript
for (let i = 0; i < 5; i++) {
  document.write("★");
}

// index.html
// <div id="stars-container"></div>

// index.js
// const starsContainer = document.getElementById("stars-container");
//
// for (let i = 0; i < 5; i++) {
//   const star = document.createElement("span");
//   star.innerHTML = "★";
//   starsContainer.appendChild(star);
// }

需求:for 循环的最大价值:循环数组

请将 数组 [' 马超 ',' 赵云 ', ' 张飞 ', ' 关羽 ',' 黄忠 '] 依次打印出来

javascript
const heroes = ["马超", "赵云", "张飞", "关羽", "黄忠"];
for (let i = 0; i < heroes.length; i++) {
  console.log(heroes[i]);
}

for 循环嵌套

利用循环的知识来对比一个简单的天文知识,我们知道地球在自转的同时也在围绕太阳公转,如果把自转和公转都看成是循环的话,就相当于是循环中又嵌套了另一个循环。

实际上 JavaScript 中任何一种循环语句都支持循环的嵌套,如下代码所示:

js
for (外部声明记录循环次数的变量; 循环条件; 变化值) {
  for (内部声明记录循环次数的变量; 循环条件; 变化值) {
    循环体;
  }
}
  • 一个循环里再套一个循环,一般用在 for 循环里
案例练习 - 打印 5 行 5 列的星星
  • 需求:页面中打印出 5 行 5 列的星星

  • 分析:

    • 利用双重 for 循环来做
    • 外层循环控制打印行,内层循环控制每行打印几个(列)
  • 升级版本:用户输入行数和列数,打印对应的星星!

js
for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; j++) {
    document.write("★");
  }
  document.write("</br>");
}
html
<!DOCTYPE html>
<html>
  <head>
    <title>打印星星</title>
  </head>
  <body>
    <label for="rows">行:</label>
    <input type="number" id="rows" />
    <br /><br />
    <label for="columns">列:</label>
    <input type="number" id="columns" />
    <br /><br />
    <button onclick="printStars()">打印星星</button>
    <br /><br />
    <pre id="output"></pre>

    <script>
      function printStars() {
        var rows = parseInt(document.getElementById("rows").value);
        var columns = parseInt(document.getElementById("columns").value);

        var output = "";

        for (var i = 0; i < rows; i++) {
          var row = "";
          for (var j = 0; j < columns; j++) {
            row += "★";
          }
          output += row + "\n";
        }

        document.getElementById("output").textContent = output;
      }
    </script>
  </body>
</html>
案例练习 - 打印倒三角形星星
  • 需求:第一行 1 个星星,第二行 2 个星星,第三行 3 个星星,第四行 4 个星星,第五行 5 个星星

  • 分析:

    • 利用双重 for 循环来做
    • 外层循环控制打印行,内层循环控制每行打印几个(列)
    • 内层循环的个数跟第几行是一一对应的
js
for (let i = 1; i <= 5; i++) {
  let stars = "";
  for (let j = 1; j <= i; j++) {
    stars += "★";
  }
  document.write(stars + "<br/>");
}
案例练习 - 九九乘法表
  • 需求:打印九九乘法表

  • 分析:

    • 只需要把刚才倒三角形星星做改动
    • ★ 换成 1 x 1 = 2 格式
js
document.write("<table>");

for (var x = 1; x <= 9; x++) {
  document.write("<tr>");
  for (var y = 1; y <= x; y++) {
    document.write("<td>" + y + " x " + x + " = " + x * y + "</td>");
  }
  document.write("</tr>");
}

document.write("</table>");
css
table {
  margin: 20px auto;
  text-align: center;
  border-collapse: collapse;
}

th,
td {
  padding: 10px;
  border: 2px solid #000;
}