news 2026/5/1 5:41:00

JavaScript学习笔记:3.控制流与错误处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JavaScript学习笔记:3.控制流与错误处理

JavaScript学习笔记:3.控制流与错误处理

上一篇搞定了JS的“内功心法”(基础语法与数据类型),这一篇咱们来解锁JS的“实战技能”——控制流与错误处理。如果说变量和数据类型是JS的“砖瓦”,那控制流就是“建筑图纸”(决定代码执行顺序),错误处理就是“安全网”(防止代码崩掉)。今天就用接地气的例子,带你吃透这些核心知识点,从此写代码能“做对决策”,还能“从容兜底”~

一、块语句:给代码划清“独立空间”

块语句是JS里最基础的“代码容器”,用一对{}把多条语句包起来,就像给代码划了个“独立房间”。它通常和控制流语句(if、for、while)搭配使用,比如:

while(奶茶没喝完){吸一口;// 这整个{}就是块语句}

但这个“房间”对不同变量的“约束力”不一样——这就是新手最容易踩的坑!

避坑重点:var vs let/const的“房间规则”

  • var:串门的“邻居”:用var声明的变量不受块语句约束,会“串门”到函数或全局作用域。比如:

    var奶茶="全糖";{var奶茶="三分糖";// 同一个变量,覆盖了外面的值}console.log(奶茶);// 输出“三分糖”——var直接“串门”改了全局变量

    这就像你在自己房间换了衣服,结果邻居的衣服也跟着变了,离谱!

  • let/const:安分守己的“住户”:用let或const声明的变量是“块级作用域”,只在自己的“房间”里生效,不会打扰外面:

    let奶茶="全糖";{let奶茶="三分糖";// 独立的局部变量}console.log(奶茶);// 输出“全糖”——外面的变量不受影响

    这才是正常的“房间规则”!所以记住:块语句里优先用let/const,彻底和var说再见

二、条件语句:JS的“决策大脑”

条件语句让JS能“根据情况做选择”,就像你出门前看天气:下雨带伞,晴天戴帽。JS里有两种核心条件语句:if...elseswitch,各有擅长场景。

1. if…else:灵活的“多岔路口”

if...else就像人生的“岔路口”,满足条件走一条路,不满足走另一条。语法很简单:

if(条件A){A;}elseif(条件B){B;}else{实在没路走,兜底方案;}

但这里藏着两个“致命坑”,新手必栽!

坑1:假值的“伪装术”

JS里有6个“假值”,它们会被条件语句当成false处理,其余全是true

  • falseundefinednull
  • 0NaN
  • 空字符串""

举个反例,你以为能判断“用户输入了内容”,结果栽了:

const用户名="";// 用户没输入,是空字符串if(用户名){console.log("欢迎登录");}else{console.log("请输入用户名");// 正确执行,因为""是假值}// 坑!如果用户输入0:const年龄=0;// 0是合法年龄,但却是假值if(年龄){console.log("年龄合法");}else{console.log("请输入合法年龄");// 错误执行!}

避坑指南:如果要判断“是否存在值”,别直接用if(变量),要用精准判断:

if(年龄!==undefined&&年龄!==null){// 排除未定义和空值console.log("年龄合法");}
坑2:条件里的“赋值陷阱”

千万别在if条件里写赋值语句(=),要写比较语句(===)!比如:

let喜欢奶茶=false;if(喜欢奶茶=true){// 这里是赋值,不是比较!console.log("给你买奶茶");// 会执行,因为赋值后喜欢奶茶变成true}

这就像你本来不喜欢奶茶,别人硬塞给你一杯,然后说“你看你喜欢吧”——逻辑完全混乱!最佳实践:条件里只写比较表达式,赋值单独写。

2. switch:高效的“多选一菜单”

当有多个固定选项需要匹配时,switch比if…else更简洁,就像餐厅里的“套餐菜单”,选一个套餐就对应一套服务。语法:

switch(套餐类型){case"汉堡套餐":给汉堡;break;// 关键!选完就退出case"披萨套餐":给披萨;break;default:给默认小吃;// 没有匹配项时的兜底}
核心坑:switch的“穿透效应”

如果忘记写break,JS会继续执行下一个case的代码,就像你点了汉堡套餐,服务员不仅给了汉堡,还自动加了披萨和小吃——完全超出预期!比如:

const水果="香蕉";switch(水果){case"香蕉":console.log("香蕉是$0.48一磅");// 没写break!case"樱桃":console.log("樱桃是$3.00一磅");break;}// 输出:香蕉是$0.48一磅 → 樱桃是$3.00一磅(穿透了!)

避坑指南:除了故意利用穿透的场景(极少),每个case后面必须加break!另外,switch的匹配是严格相等(===),不会自动类型转换,比如case "1"case 1是两个不同的匹配项。

三、异常处理:JS的“安全网”——与bug和平共处

写代码难免遇到bug(就像走路难免摔跤),异常处理就是给代码装“安全网”,让它摔得轻一点,甚至能爬起来继续走。JS的异常处理核心是try...catch...finally,再加上throw自定义错误。

1. 三兄弟分工:try→尝试,catch→补救,finally→兜底

这三个语句的关系就像“快递签收流程”:

  • try:尝试做一件事(比如签收快递)
  • catch:如果出问题(快递损坏、丢件),就补救
  • finally:不管成没成功(签没签收),必须做的事(比如关门、谢谢快递员)

举个完整例子:

function签收快递(快递状态){if(快递状态==="损坏"){thrownewError("快递损坏,无法签收");// 主动抛出错误(丢件了!)}return"签收成功";}try{// 尝试签收const结果=签收快递("损坏");console.log(结果);}catch(错误){// 出问题了,补救console.error("出错了:",错误.message);// 输出错误信息联系商家理赔();// 补救措施}finally{// 不管怎样都要做console.log("快递处理完毕,关门");// 必执行!}

输出结果:

出错了:快递损坏,无法签收 快递处理完毕,关门

2. throw:主动“喊救命”——自定义错误

throw就像你发现快递有问题时,主动喊“快递员,这里有问题!”。它可以抛出任意类型的值(字符串、数字、对象),但最佳实践是抛出Error对象,因为它自带name(错误类型)和message(错误信息),方便调试:

// 不推荐:抛出字符串throw"快递损坏";// 推荐:抛出Error对象thrownewError("快递损坏,无法签收");// name: "Error", message: "快递损坏..."

还可以用更具体的错误类型,比如TypeError(类型错误)、RangeError(范围错误),让错误信息更精准:

function计算年龄(出生年份){if(typeof出生年份!=="number"){thrownewTypeError("出生年份必须是数字");// 类型错误}if(出生年份<1900||出生年份>2024){thrownewRangeError("出生年份范围必须是1900-2024");// 范围错误}return2024-出生年份;}

3. finally的“霸道逻辑”:覆盖一切返回值

finally有个很“霸道”的特性:不管try或catch里有没有return,finally都会执行,而且如果finally里有return,会直接覆盖前面的返回值!比如:

function测试(){try{return"try的返回值";}catch(e){return"catch的返回值";}finally{return"finally的返回值";// 覆盖前面的返回值}}console.log(测试());// 输出:finally的返回值

这就像你本来想签收快递(return try的结果),但最后不管怎样,都必须执行“关门”(finally的return),直接忽略了之前的想法。避坑指南:finally里尽量不要写return,它的核心用途是“释放资源”(比如关闭文件、断开网络连接),而不是返回值。

4. 错误处理的“避坑红线”

  • 别“吞掉”错误:catch块里不要只写console.log(e),要用console.error(e)(会格式化错误,方便调试),更不要空catch(catch(){}, 相当于把bug藏起来,永远找不到)。
  • 精准捕获:不要用try包裹所有代码,只包裹“可能出错的部分”(比如网络请求、数据解析),否则会掩盖真正的问题。
  • 释放资源:文件、网络连接、定时器等资源,一定要放在finally里释放,避免内存泄漏。

四、总结:控制流与错误处理的“核心心法”

  1. 块语句:用{}划清作用域,let/const是块级作用域,var是“串门户”,坚决不用var。
  2. 条件语句:
    • if…else:警惕假值陷阱,条件里不写赋值,复杂判断用块语句。
    • switch:每个case必加break,用default兜底,匹配是严格相等。
  3. 异常处理:
    • try:包裹可能出错的代码,不滥用。
    • catch:精准处理错误,不吞错,用Error对象。
    • finally:释放资源,不写return。

JS的控制流让代码“有逻辑、会决策”,错误处理让代码“抗造、不脆断”。这两个技能结合起来,你写的代码就从“勉强能跑”变成“稳健可靠”了~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 17:50:58

简点到家“数字化+轻资产”双轮驱动,加速发展家政市场

当前&#xff0c;家政服务市场正处于快速发展阶段&#xff0c;众多中小家政企业主在广阔的市场前景下&#xff0c;也普遍面临着“增长不增利”的经营压力。如何有效应对获客成本高企、服务标准化缺失等难题&#xff0c;已成为行业关注的重点。一、获客成本高企挤压利润空间传统…

作者头像 李华
网站建设 2026/4/25 13:17:14

高并发电商场景:JVM资源规划实战

文章目录高并发电商场景&#xff1a;JVM资源规划实战TPS→线程→内存换算关系、GC选择策略与瓶颈点优化&#x1f4cb; 目录&#x1f3ea; 一、电商高并发场景特征分析&#x1f4a1; 电商流量特征分析&#x1f3af; 电商应用负载特征&#x1f522; 二、TPS→线程→内存换算公式体…

作者头像 李华
网站建设 2026/4/19 19:29:27

Draco 3D压缩技术:如何让你的3D模型体积缩小90%?

Draco 3D压缩技术&#xff1a;如何让你的3D模型体积缩小90%&#xff1f; 【免费下载链接】draco Draco is a library for compressing and decompressing 3D geometric meshes and point clouds. It is intended to improve the storage and transmission of 3D graphics. 项…

作者头像 李华
网站建设 2026/4/21 12:38:12

终极图像量化神器:libimagequant完全指南

终极图像量化神器&#xff1a;libimagequant完全指南 【免费下载链接】libimagequant Palette quantization library that powers pngquant and other PNG optimizers 项目地址: https://gitcode.com/gh_mirrors/li/libimagequant 在当今数字时代&#xff0c;图像优化已…

作者头像 李华
网站建设 2026/4/14 2:30:30

QUIC协议实战指南:构建下一代高性能P2P传输系统

QUIC协议实战指南&#xff1a;构建下一代高性能P2P传输系统 【免费下载链接】iroh Sync anywhere 项目地址: https://gitcode.com/GitHub_Trending/ir/iroh 在当今分布式应用蓬勃发展的时代&#xff0c;传统P2P传输技术正面临严峻挑战。视频会议卡顿、文件传输中断、移动…

作者头像 李华
网站建设 2026/4/24 7:46:32

智能代码补全革命:YouCompleteMe让Vim编程效率倍增

智能代码补全革命&#xff1a;YouCompleteMe让Vim编程效率倍增 【免费下载链接】YouCompleteMe 项目地址: https://gitcode.com/gh_mirrors/you/YouCompleteMe 想要在Vim中体验真正现代化的智能代码补全功能吗&#xff1f;YouCompleteMe&#xff08;YCM&#xff09;正是…

作者头像 李华