JavaScript 流程控制全解析:从基础结构到实战应用
一、什么是流程控制?
在编程中,流程控制是指控制程序执行顺序的机制。通过流程控制,我们可以让程序根据不同条件执行不同逻辑,重复执行特定代码块,或跳转执行位置。JavaScript 作为前端开发的核心语言,提供了丰富的流程控制结构,本文将结合理论与实战,带你全面掌握流程控制的核心要点。
二、流程控制结构分类
JavaScript 流程控制主要分为四大类:
- 顺序结构:程序默认按代码顺序逐行执行(无需额外语法,最基础的执行方式)。
- 分支结构:根据条件判断选择执行路径(
if
、switch
)。 - 循环结构:满足条件时重复执行代码块(
for
、while
、do...while
)。 - 跳转结构:强制改变执行位置(
break
、continue
)。
三、分支结构:条件判断的核心
3.1 if 语句家族
(1)单分支 if
语法:
if (条件) {// 条件为true时执行
}
案例:判断是否成年
let age = 18
if(age >= 18){console.log('已成年')
}
运行结果:
(2)双分支 if...else
语法:
if (条件) {// 条件成立执行的代码
} else {// 条件不成立执行的代码
}
案例:判断成绩是否及格
let score = 78
if(score >= 60){console.log('及格')
}else{console.log('不及格')
}
运行结果:
(3)多分支 if...else if...else
语法:
if (条件1) {
// 条件1成立执行的代码}
else if (条件2) {
// 条件2成立执行的代码}
else {
// 都不成立的时候执行的代码
}
案例:判断成绩不及格,及格,良好,优秀的四个等级
let fen = 64
if(fen >= 90){console.log('优秀')
}else if(fen >= 80){console.log('良好')
}else if(fen >= 60){console.log('及格')
}else{console.log('不及格')
}
运行结果:
(4)三元表达式(本质上是if...else 简写)
语法:下面是Python和JS中两种语言中的三元运算符,大家可以比较并加以区分。
const result = 条件判断语句 ? 真返回的结果 : 假返回的结果; //js
num = 真返回的结果 if 条件判断语句 else 假返回的结果 //Python
案例:
let My_sorce = 80
let result = My_sorce >= 60 ? '太棒了,你及格了!':'你真菜,滚回去吧!'
console.log(result)
运行结果:
3.2 switch 语句:多条件匹配的优选
语法:
switch (表达式) {case 值1: 代码; break;case 值2: 代码; break;default:代码; // 可选
}
工作原理:
通过===
严格匹配表达式与 case 值,匹配成功则执行对应代码,break
用于阻止穿透。
案例:判断星期几(含穿透实例)
let day = 2
switch (day){case 1:console.log('星期一');break;case 2:console.log('星期二')// 这里没有break,出现穿透现象,打印下一个case中的语句case 3:console.log('星期三')break; // 有break,不会穿透到下一个case语句中case 4:console.log('星期四')break;case 5:console.log('星期五')break;case 6:console.log('星期六')break;case 7:console.log('星期日')break;default:console.log('输入的数字有误!')break;
}
运行结果:
穿透的定义:
在 JavaScript 中,switch 语句中的“穿透”(Fall-through)是指 当某个 case 分支匹配后,若没有使用 break 语句结束当前分支,则程序会继续执行下一个 case 或 default 分支的代码。这种行为称为“穿透”,也叫“fall-through”。
穿透使用演示:判断春夏秋冬四季
let num_month = 2
switch (num_month){case 3:case 4:case 5:console.log('春季')break;case 6:case 7:case 8:console.log('夏季')break;case 9:case 10:case 11:console.log('秋季')break;case 12:case 1:case 2:console.log('冬季')break;
}
穿透总结:
1.穿透(Fall-through) 是指在 switch 语句中,匹配到某个 case 后,如果没有使用 break,程序会继续执行后续分支。
3.优点:可以用于多个 case 共享相同的代码逻辑。
4.缺点:如果不小心遗漏了 break,可能导致意外的行为。
5.建议:除非有意利用穿透特性,否则应在每个 case 分支后加上 break。
四、循环结构:重复执行的利器
4.1 for 循环:已知次数的首选
语法:
for (初始化; 条件判断; 迭代更新) {// 循环体
}
案例:遍历数组求和
let sum = 0
let array = [1,2,3,4,5]
for(let i = 0; i < array.length; i++){sum += array[i]
}
console.log(`这个数组的和为:${sum}`)
运行结果:
4.2 while 循环:条件驱动的循环
语法:
let 计数器 = 初始值;
while (条件) {// 循环体计数器++; // 务必更新计数器,避免死循环!
}
案例:计算 1-100 累加和
let sum1 = 0,i = 1
while (i <= 100){sum1 += ii++
}
console.log(`0-100的累加和为:${sum1}`)
运行结果:
4.3 do...while 循环:至少执行一次的循环
语法:
let 计数器 = 初始值;
do {// 循环体(先执行一次)计数器++;
} while (条件); // 后判断条件
案例:用户输入验证,有三次登录机会(至少会执行一次)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>登录验证</title>
</head>
<body><script>let username = 'admin'let password = '123456'let count = 0do{let input_username = prompt('请输入用户名:')let input_password = prompt('请输入密码:')if(input_username === username && input_password === password){alert('登录成功')break}else{count++alert(`用户名或密码错误,还有:${3-count}次机会!`)if (count ===3){alert('登录机会已用完,登录失败')break}}}while (count<=3);</script>
</body>
</html>
五、跳转结构:灵活控制执行流
5.1 continue:跳过本次循环
作用:终止当前循环迭代,直接进入下一次循环。
案例:过滤偶数,只打印奇数
for(let i = 0; i < 10; i++){if(i%2===0){continue}console.log(i)
}
运行结果:
5.2 break:退出整个循环
作用:立即终止所在循环,执行循环后的代码。
案例:找到第一个偶数时停止循环
for(let i = 1; i < 10; i++){if(i%2===0){break}console.log(i)
}
运行结果:
六、补充:对象与数组的遍历
6.1 for-in:遍历对象属性(不推荐数组)
示例:
let students = {'name':'小宁','age':18,'sex':'男','hobby':'写代码'
}
for (const key in students){console.log(key,':',students[key])
}
运行结果:
注意:会遍历继承的属性,可通过hasOwnProperty()
过滤。
6.2 for-of:遍历可迭代对象(推荐数组)
示例:
let my_array = ['小米','华为','vivo','oppo','锤子手机']
for (const item of my_array){console.log(item)
}
运行结果:
支持类型:数组、字符串、Map、Set 等可迭代对象。
七、综合案例:学生成绩管理系统
需求:统计班级学生成绩,输出各等级人数,并找出最高分学生。
// 模拟学生数据(数组包含对象)
const students = [{ name: "张三", score: 85 },{ name: "李四", score: 92 },{ name: "王五", score: 78 },{ name: "赵六", score: 95 },
];
// 记录最高分和最高分学生名
let max_score = 0,top_student_name = ''
// 记录各个等级学生的数量
let A_count = 0,B_count = 0,C_count = 0// 运行for--of对数组循环遍历
for(const student of students){const {name,score} = student; //解构赋值// 记录最高分if(score > max_score) {max_score = scoretop_student_name = name}// 记录各个等级学生的数量if(score >= 90){A_count++}else if(score >= 80){B_count++}else if(score >= 60){C_count++}else{// 跳过不及格的学生,进入下次循环,不干扰后续对ABC等级的评判continue;}// 使用三元运算符单独输出学生信息(包含三元运算符的嵌套)console.log(`${name}同学的等级为:${score >= 90 ? 'A' : score >= 80 ? 'B' : 'C'}`);
}
//输出统计后的结果
console.log("\n统计结果:")
console.log(`A等级学生数量为:${A_count}`);
console.log(`B等级学生数量为:${B_count}`);
console.log(`C等级学生数量为:${C_count}`);
console.log(`最高分是:${max_score},最高分学生是:${top_student_name}`);
运行结果:
针对解构赋值的补充:
1.解构赋值的定义:
在 JavaScript 中,解构赋值(Destructuring Assignment) 是一种从数组或对象中提取数据,并将其赋值给变量的简洁语法。它允许我们以更清晰、更简洁的方式从复杂的数据结构中提取所需的值。
2.实例说明:
·对象解构赋值:
let student = {name:'张三',age:18,sex:'男'
}
let {name,age,sex} = student
console.log(name,age,sex)
运行结果:
·数组解构赋值:
let arry = [1,2,3,4,5]
let [a,b,c,d,e] = arry
console.log(a,b,c,d,e)
运行结果:
八、核心内容总结
本文系统梳理了 JavaScript 流程控制的四大结构及典型应用,帮助读者建立从理论到实践的完整认知:
-
顺序结构
- 程序默认的执行逻辑,按代码顺序逐行运行,无需额外语法,是一切流程控制的基础。
-
分支结构:条件驱动的决策核心
if
家族:- 单分支:条件为真时执行(如权限判断)。
- 双分支:非此即彼的逻辑(如登录状态提示)。
- 多分支:多条件逐级判断(如订单状态分类)。
- 三元表达式:极简版双分支(适合简单赋值场景)。
switch
语句:等值匹配的高效选择,通过break
避免穿透,适合多值映射(如星期、季节转换)。
-
循环结构:重复逻辑的自动化
for
循环:适用于已知次数的场景(如遍历数组、生成列表)。while
循环:条件驱动的 “先判断后执行”(如用户输入验证)。do...while
循环:至少执行一次的 “先执行后判断”(如重试机制)。- 遍历增强:
for-in
:遍历对象属性(需过滤继承属性)。for-of
:遍历可迭代对象(数组、字符串等,推荐替代传统for
循环)。
-
跳转结构:灵活控制执行流
continue
:跳过当前循环迭代(如过滤无效数据)。break
:提前终止整个循环(如找到目标值后退出)。
-
实战应用与最佳实践
- 通过 “学生成绩管理系统” 综合案例,演示如何组合使用分支、循环和跳转结构,实现复杂业务逻辑。
- 强调代码可读性与逻辑清晰性,避免过度依赖穿透(
switch
)或嵌套循环,优先使用解构赋值、for-of
等现代语法简化代码。