当前位置: 首页 > news >正文

lesson59:JavaScript 控制流详解:分支结构与循环语句全指南

目录

一、分支结构:让程序学会"做选择"

1. if 语句:灵活的条件判断

1.1 常见形式与应用场景

1.2 嵌套 if 与注意事项

2. switch 语句:多值匹配的高效方案

2.1 核心特性与示例

2.2 if-else vs switch:如何选择?

二、循环语句:高效处理重复任务

1. for 循环:最经典的计数循环

1.1 执行流程解析

1.2 基础用法与变种

2. while 循环:条件驱动的循环

2.1 典型应用场景

2.2 警惕无限循环!

3. do-while 循环:至少执行一次的循环

3.1 适用场景:先执行后判断

4. 现代循环:for...of 与 for...in(ES6+)

4.1 for...of:遍历可迭代对象

4.2 for...in:遍历对象属性

5. 循环选择指南:哪种循环最适合你?

三、循环控制与高级技巧

1. 循环控制语句:break 与 continue

2. 标签语句:跳出多层循环

3. 性能优化:减少循环开销

四、总结与最佳实践

核心知识点回顾

编写高质量代码的建议


在 JavaScript 编程中,控制流是构建逻辑的核心。无论是根据用户输入展示不同内容,还是处理大量数据,都离不开分支结构循环语句的灵活运用。本文将系统讲解 JavaScript 中的分支结构(if/switch)与循环语句(for/while/do-while),结合实例分析其适用场景与最佳实践,帮助你写出更高效、更可读的代码。

一、分支结构:让程序学会"做选择"

分支结构允许程序根据不同条件执行不同代码块,是实现"决策逻辑"的基础。JavaScript 提供两种主要分支结构:if 语句switch 语句

1. if 语句:灵活的条件判断

if 语句是最常用的分支结构,通过布尔条件决定代码执行路径。其基本语法如下:

// 基础语法
if (条件表达式) {
// 条件为 true 时执行
} else if (条件表达式2) {
// 条件1为 false,条件2为 true 时执行
} else {
// 所有条件都为 false 时执行
}
1.1 常见形式与应用场景
  • 单条件判断(if):适用于单一条件场景,如用户登录验证

    const isLoggedIn = checkUserStatus();
    if (isLoggedIn) {
    renderDashboard(); // 用户已登录,渲染控制台
    }
  • 二选一判断(if-else):处理互斥条件,如权限控制

    if (user.role === 'admin') {
    showAdminPanel(); // 管理员显示管理面板
    } else {
    showUserPanel(); // 普通用户显示用户面板
    }
  • 多条件判断(if-else if-else):处理多种可能结果,如成绩评级

    const score = 85;
    if (score >= 90) {
    console.log('优秀');
    } else if (score >= 80) {
    console.log('良好'); // 输出:良好
    } else if (score >= 60) {
    console.log('及格');
    } else {
    console.log('不及格');
    }
1.2 嵌套 if 与注意事项

嵌套 if 可处理复杂条件,但过度嵌套会导致"回调地狱"式的代码(如 if (a) { if (b) { if (c) { ... } } })。建议:

  • 条件合并:用逻辑运算符(&&/||/!)简化多层条件
  • 提前返回:将简单条件放在前面,减少嵌套层级
  • 使用三元表达式:处理简单二选一逻辑(但避免嵌套三元)
// 优化前:嵌套 if
if (user) {
if (user.isVerified) {
if (user.hasPermission) {
allowAccess();
} else {
showError('无权限');
}
} else {
showError('未验证');
}
} else {
showError('未登录');
}// 优化后:提前返回 + 条件合并
if (!user) return showError('未登录');
if (!user.isVerified) return showError('未验证');
if (!user.hasPermission) return showError('无权限');
allowAccess();

2. switch 语句:多值匹配的高效方案

当需要根据固定值执行不同逻辑时,switch 比 if-else 更简洁。其语法结构如下:

switch (表达式) {
case 值1:
// 表达式 === 值1 时执行
break; // 跳出 switch
case 值2:
// 表达式 === 值2 时执行
break;
default:
// 所有 case 不匹配时执行(可选)
}
2.1 核心特性与示例
  • 严格匹配:使用 === 比较,类型和值必须完全一致
  • case 穿透:缺少 break 会继续执行下一个 case(可利用此特性合并逻辑)
  • default 子句:处理未匹配的情况,建议始终添加以避免逻辑遗漏
// 根据月份判断季节(利用穿透特性)
const month = 3;
switch (month) {
case 12:
case 1:
case 2:
console.log('冬季');
break;
case 3: // 3月匹配此 case,因无 break 会穿透到 case 4
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;
default:
console.log('无效月份');
}
2.2 if-else vs switch:如何选择?

场景推荐使用原因
范围条件(如 x > 10if-elseswitch 仅支持固定值匹配,不支持范围判断
固定值匹配(如状态码)switch代码更简洁,避免冗长的 else if (x === value)
少量条件(≤3个)if-else无需额外语法(break/default),可读性更高
多条件且值离散switch执行效率更高(引擎可优化为跳转表),且逻辑分组更清晰

二、循环语句:高效处理重复任务

循环语句用于重复执行代码块,是处理数组、集合等数据的必备工具。JavaScript 提供四种循环方式:forwhiledo-whilefor...of/for...in(ES6+)。

1. for 循环:最经典的计数循环

for 循环适合已知循环次数的场景,语法结构清晰,控制力强:

for (初始化表达式; 条件表达式; 增量表达式) {
// 循环体
}
1.1 执行流程解析
  1. 初始化:执行一次(如 let i = 0
  2. 条件判断:若为 true,执行循环体;否则退出循环
  3. 增量更新:执行循环体后更新变量(如 i++
  4. 重复步骤 2-3
1.2 基础用法与变种
  • 标准 for 循环:遍历数组(最常用场景)

    const fruits = ['苹果', '香蕉', '橙子'];
    for (let i = 0; i < fruits.length; i++) {
    console.log(`第${i+1}个水果:${fruits[i]}`);
    }
    // 输出:
    // 第1个水果:苹果
    // 第2个水果:香蕉
    // 第3个水果:橙子
  • 反向循环:从数组末尾开始遍历

    for (let i = fruits.length - 1; i >= 0; i--) {
    console.log(fruits[i]); // 橙子、香蕉、苹果
    }
  • 跳过/终止循环:使用 continue(跳过当前迭代)和 break(终止整个循环)

    // 求1-100间偶数之和(跳过奇数)
    let sum = 0;
    for (let i = 1; i <= 100; i++) {
    if (i % 2 !== 0) continue; // 跳过奇数
    sum += i;
    if (sum > 1000) break; // 超过1000时提前终止
    }
    console.log(sum); // 1050(1+3+...+45=1035,+47=1082>1000,故终止于46的和1015?需计算验证)
  • 无限循环:需谨慎使用,必须在循环体内有退出条件

    for (;;) { // 等价于 while(true)
    const input = prompt('输入"quit"退出');
    if (input === 'quit') break;
    console.log('你输入了:', input);
    }

2. while 循环:条件驱动的循环

while 循环适合循环次数不确定的场景,仅在条件为 true 时执行:

while (条件表达式) {
// 循环体(需包含条件更新逻辑,避免无限循环)
}
2.1 典型应用场景
  • 等待某个条件满足:如轮询等待数据加载完成

    let data = null;
    while (!data) {
    data = fetchData(); // 假设 fetchData() 可能返回 null
    if (!data) await sleep(1000); // 未获取到数据,等待1秒重试
    }
    processData(data);
  • 用户输入验证:确保输入符合要求

    let age;
    while (isNaN(age) || age < 0 || age > 120) {
    age = Number(prompt('请输入有效年龄(0-120):'));
    }
    console.log('你的年龄是:', age);
2.2 警惕无限循环!

while 循环最常见的错误是条件永远为 true,导致浏览器卡死。避免方式:

  • 确保循环体内有修改条件的逻辑(如 count++
  • 添加安全机制(如最大重试次数):
    let retryCount = 0;
    while (retryCount < 5) { // 最多重试5次
    if (connect()) break;
    retryCount++;
    await sleep(1000);
    }
    if (retryCount === 5) console.error('连接失败');

3. do-while 循环:至少执行一次的循环

do-while 是后测试循环,无论条件如何,循环体至少执行一次

do {
// 循环体
} while (条件表达式); // 注意末尾分号
3.1 适用场景:先执行后判断
  • 初始化操作:如加载配置文件,即使配置为空也需执行一次解析
  • 菜单交互:确保用户至少看到一次菜单选项
    let choice;
    do {
    console.log(`1. 查看信息\n2. 修改信息\n3. 退出`);
    choice = prompt('请选择操作(1-3):');
    switch (choice) {
    case '1': showInfo(); break;
    case '2': editInfo(); break;
    case '3': console.log('退出程序'); break;
    default: alert('无效选项');
    }
    } while (choice !== '3'); // 选择3时退出

4. 现代循环:for...of 与 for...in(ES6+)

ES6 引入了更简洁的循环语法,尤其适合遍历数据集合。

4.1 for...of:遍历可迭代对象

用于遍历数组、字符串、Map、Set等可迭代对象(Iterable),直接获取值而非索引:

// 遍历数组
const numbers = [10, 20, 30];
for (const num of numbers) {
console.log(num * 2); // 20、40、60
}// 遍历字符串
for (const char of 'hello') {
console.log(char.toUpperCase()); // H、E、L、L、O
}// 遍历 Map
const user = new Map([['name', '张三'], ['age', 25]]);
for (const [key, value] of user) {
console.log(`${key}: ${value}`); // name: 张三,age: 25
}
4.2 for...in:遍历对象属性

用于遍历对象的可枚举属性(包括继承的属性),返回属性名:

const person = { name: '李四', age: 30, city: '北京' };
for (const key in person) {
if (person.hasOwnProperty(key)) { // 过滤继承属性
console.log(`${key}: ${person[key]}`);
}
}
// 输出:
// name: 李四
// age: 30
// city: 北京

⚠️ 注意

  • 不要用 for...in 遍历数组(可能遍历到非数字索引的属性)
  • 始终用 hasOwnProperty 过滤原型链属性

5. 循环选择指南:哪种循环最适合你?

场景推荐循环优势
遍历数组(已知索引)for / for...offor 可控制步长(如 i+=2),for...of 更简洁
遍历对象属性for...in专门为对象属性设计,返回键名
遍历可迭代对象(Map/Set/字符串)for...of直接获取值,支持解构赋值
循环次数不确定(条件控制)while逻辑更清晰,避免冗余的初始化代码
至少执行一次do-while无需提前初始化条件变量
异步循环(如等待Promise)for...of + async/await支持 await 语法(普通 for 循环也可)

三、循环控制与高级技巧

1. 循环控制语句:break 与 continue

  • break:立即终止整个循环,跳到循环后的代码

    // 查找数组中第一个偶数
    const nums = [1, 3, 5, 4, 7];
    let firstEven;
    for (const num of nums) {
    if (num % 2 === 0) {
    firstEven = num;
    break; // 找到后立即退出循环
    }
    }
    console.log(firstEven); // 4
  • continue:跳过当前迭代,直接进入下一次循环

    // 计算数组中奇数之和
    const nums = [1, 2, 3, 4, 5];
    let sum = 0;
    for (const num of nums) {
    if (num % 2 === 0) continue; // 跳过偶数
    sum += num;
    }
    console.log(sum); // 1+3+5=9

2. 标签语句:跳出多层循环

嵌套循环中,可通过标签语句跳出外层循环(不推荐过度使用,建议拆分为函数):

outerLoop: for (let i = 0; i < 3; i++) {
innerLoop: for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
break outerLoop; // 直接跳出 outerLoop
}
console.log(`i=${i}, j=${j}`);
}
}
// 输出:
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0(然后 break outerLoop)

3. 性能优化:减少循环开销

  • 缓存数组长度:避免每次循环都计算 arr.length

    // 优化前
    for (let i = 0; i < arr.length; i++) { ... }// 优化后
    for (let i = 0, len = arr.length; i < len; i++) { ... }
  • 避免在循环中操作 DOM:DOM 操作昂贵,建议批量处理

    // 优化前(每次循环操作DOM)
    for (const item of list) {
    document.getElementById('container').innerHTML += `<div>${item}</div>`;
    }// 优化后(先拼接字符串,再一次性更新)
    let html = '';
    for (const item of list) {
    html += `<div>${item}</div>`;
    }
    document.getElementById('container').innerHTML = html;
  • 使用 typedArray:处理大量数字时,Uint8Array 等类型数组比普通数组更快

四、总结与最佳实践

核心知识点回顾

  • 分支结构:用 if-else 处理灵活条件,switch 处理固定值匹配
  • 循环语句for 适合计数,while 适合条件控制,for...of 适合遍历数据
  • 控制流break 终止循环,continue 跳过迭代,标签语句处理嵌套循环

编写高质量代码的建议

  1. 可读性优先:避免过度嵌套(分支/循环),复杂逻辑拆分为函数
  2. 选择合适工具:根据场景选择分支/循环类型(如范围条件用 if,固定值用 switch)
  3. 防御性编程:循环添加边界条件,避免无限循环;分支添加 default 处理异常情况
  4. 利用现代语法:优先使用 for...ofconst/let 等 ES6+ 特性,减少 var 导致的作用域问题
  5. 代码复用:重复逻辑抽象为函数(如将循环逻辑封装为工具函数)

控制流是 JavaScript 的骨架,掌握分支与循环不仅能解决当前问题,更能培养结构化思维。通过大量实践(如实现排序算法、处理API数据),你将能灵活运用这些工具,写出高效、优雅的代码!

下一步学习建议:结合函数、数组方法(forEach/map/filter)深入理解声明式编程,对比命令式循环的优劣。


文章转载自:

http://Hp1bT7aU.Lkthj.cn
http://huqalUvm.Lkthj.cn
http://rAOP8HvN.Lkthj.cn
http://0CcR49Kw.Lkthj.cn
http://DUu2ONEZ.Lkthj.cn
http://rtVyU0Qr.Lkthj.cn
http://g99OxTrn.Lkthj.cn
http://Mqth2nFM.Lkthj.cn
http://g6F6syTX.Lkthj.cn
http://lIgomYu2.Lkthj.cn
http://9p5ec4dX.Lkthj.cn
http://vvLtyZAH.Lkthj.cn
http://6NS23xyq.Lkthj.cn
http://H78etByj.Lkthj.cn
http://NZMkgxU8.Lkthj.cn
http://H7xpjnW5.Lkthj.cn
http://ZdDdXejU.Lkthj.cn
http://krH4vENk.Lkthj.cn
http://r8QnquMn.Lkthj.cn
http://QSfwa3VU.Lkthj.cn
http://gIh81xOz.Lkthj.cn
http://T5gRtr8x.Lkthj.cn
http://roC7l9Yc.Lkthj.cn
http://8hwXOdpz.Lkthj.cn
http://J3kXlhSU.Lkthj.cn
http://mwPvT7YO.Lkthj.cn
http://J3xdc69b.Lkthj.cn
http://TuTnwuEL.Lkthj.cn
http://BM4gO7Hq.Lkthj.cn
http://xph3IZPY.Lkthj.cn
http://www.dtcms.com/a/380004.html

相关文章:

  • Avalonia 基础导航实现:从页面切换到响应式交互全指南
  • 【连载2】C# MVC 自定义错误页设计:404/500 处理与 SEO 优化
  • java jdbc连接sqlserver2008R2版本数据库报错,驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接
  • 企业级AI大模型选型指南:从评估部署到安全实践
  • Spring Boot + Redis 缓存性能优化实战:从5秒到毫秒级的性能提升
  • 【Vue2手录09】购物车实战
  • 【论文阅读】Uncertainty Modeling for Out-of-Distribution Generalization (ICLR 2022)
  • PAT乙级_1111 对称日_Python_AC解法_无疑难点
  • Kafka面试精讲 Day 16:生产者性能优化策略
  • vue 批量自动引入并注册组件或路由
  • Kubernetes(K8s)详解
  • 趣味学solana(介绍)
  • Apache Thrift:跨语言服务开发的高性能RPC框架指南
  • Flutter 应用国际化 (i18n) 与本地化 (l10n) 完整指南
  • 第 5 篇:深入浅出学 Java 语言(JDK8 版)—— 精通类与对象进阶,掌握 Java 面向对象核心能力
  • Gin-Vue-Admin学习笔记
  • Golang關於信件的
  • The 2024 ICPC Asia East Continent Online Contest (I)
  • 【数所有因子和快速新解/范围亲密数/分解因式怎么去掉重复项】2022-10-31
  • SQL语句执行时间太慢,有什么优化措施?以及衍生的相关问题
  • 【论文阅读】Language-Guided Image Tokenization for Generation
  • PHP:从入门到实战的全方位指南
  • 经典动态规划题解
  • 商城购物系统自动化测试报告
  • [工作表控件20] 拼音排序功能:中文数据高效检索实战指南
  • 9120 部 TMDb 高分电影数据集 | 7 列全维度指标 (评分 / 热度 / 剧情)+API 权威源 | 电影趋势分析 / 推荐系统 / NLP 建模用
  • 【Java】多态
  • LeetCode热题 438.找到字符中所有字母异位词 (滑动窗口)
  • 解决 N1 ARMBIAN Prometheus 服务启动失败问题
  • Linux 正则表达式详解(基础 + 扩展 + 实操)