Switch 里能塞表达式吗?前端老铁都踩过的坑全解析


Switch 里能塞表达式吗?前端老铁都踩过的坑全解析

  • Switch 里能塞表达式吗?前端老铁都踩过的坑全解析
    • 先把话撂这儿:switch 不是垃圾桶,啥都往里倒真的会炸
    • JS 引擎视角:switch 到底干了啥?
    • 基础类型随便玩?别高兴太早
    • 对象、数组直接往里丢?门儿都没有
    • 函数调用、三元、模板字符串——能算就行,但别作死
      • 1. 函数调用当 case
      • 2. 三元运算当 case
      • 3. 模板字符串当 case
    • 实战:大厂开源项目咋玩的?
      • 案例 1:React-Router 路由匹配
      • 案例 2:Ant Design 把响应码翻译成文案
      • 案例 3:Vuex 状态机
    • 为啥你写的表达式总进不去?排查三步走
    • 让 switch 更香的四个骚技巧
      • 技巧 1:复杂逻辑先抽到变量
      • 技巧 2:立即执行函数包裹异步?别闹
      • 技巧 3:Map/Object 做兜底,比 default 更灵活
      • 技巧 4:switch(true) 虽香,别滥用
    • 最后一盆冷水:别为了炫技把 switch 写成谜语人
    • 彩蛋:终极 cheat-sheet(直接复制到备忘录)

Switch 里能塞表达式吗?前端老铁都踩过的坑全解析

友情提示:本文全程口语化,代码管饱,吐槽管够。阅读时请自备瓜子,看到血压升高的段落别砸键盘,砸坏了还得自己掏钱买新的。


先把话撂这儿:switch 不是垃圾桶,啥都往里倒真的会炸

我当年第一次用 switch,是在一个周五的傍晚。PM 站在背后催进度,我脑子一热,把case a + b:啪地敲进去,还自我感觉良好——直到浏览器啪地给我返回一个default,我当时就懵了:我算得明明等于 3 啊,凭啥不进?
那一刻我才意识到,这玩意儿跟if完全不是一个物种。switch 的匹配是全等比较(===),不带隐式类型转换,也不吃你那一套“差不多就行”。于是就有了今天这篇血泪总结:到底哪些表达式能塞,哪些不能塞,塞进去又怎么保证不翻车。


JS 引擎视角:switch 到底干了啥?

先别急着写代码,咱把引擎的小算盘摸清楚。下面这段是 V8 字节码的“翻译版”,人类能看懂:

// 源代码letcolor='red';switch(color){case'red':console.log('番茄炒蛋');break;case'blue':console.log('蓝莓慕斯');break;default:console.log('黑暗料理');}

引擎眼里:

  1. 先算一遍color求值结果(这里只是变量读取,够简单)。
  2. 把结果跟每个case求值结果===对比。
  3. 一旦命中,就跳到对应位置,不会帮你自动break;如果你忘了写,它就一路滑到底(俗称 fallthrough)。

注意关键词:求值结果、===、不会自动 break
记住这三兄弟,后面所有坑都是他们挖的。


基础类型随便玩?别高兴太早

字符串、数字、布尔值,这三个老实人当然没问题:

functiontip(type){switch(type){case1:return'info';case'error':return'danger';casetrue:return'success';default:return'secondary';}}

但有两个暗雷:

  1. NaN永远不等于自身,所以case NaN:永远进不去。
  2. +0-0===眼里是一家人,但Object.is(+0, -0)会判离异。switch 用的是===,所以+0-0会滑进同一个 case。
switch(NaN){caseNaN:console.log('看得到算我输');// 不会执行}

对象、数组直接往里丢?门儿都没有

来看个活生生的翻车现场:

consta=[1,2,3];constb=[1,2,3];switch(a){caseb:console.log('相等吗?');break;default:console.log('不相等!');// 走到这里}

数组是引用类型,a === b比较的是引用地址,不是结构。
同理,对象、函数、正则、Date 都一样,只有同一个引用才算命中
所以别把“长得像”当成“真相等”,switch 不吃这一套。


函数调用、三元、模板字符串——能算就行,但别作死

switch 只认表达式最终的求值结果,至于你中间是函数、是三元、是模板字符串,它不管,只要能算出值且后面跟着 === 比较,就能玩。
但“能玩” ≠ “好玩”。先看几个骚操作:

1. 函数调用当 case

functiongetType(){return'success';}switch('success'){casegetType():// 先执行函数,拿到 'success'console.log('命中');break;default:console.log('没命中');}

上面这段完全合法,函数先执行,返回'success',然后switch'success' === 'success',命中。
但注意:

  • 函数里不要有副作用(比如改外部变量),否则调试时会想打人。
  • 如果函数里异步,那就 GG 了,switch 是同步的,不会等你 Promise resolve。

2. 三元运算当 case

constlang='en';switch(lang){caselang==='en'?'hello':'你好':console.log('hi');break;}

三元运算最后算出'hello',所以lang === 'hello'不成立,进不去。
switch (lang)改成switch ('hello')就能进。
逻辑没毛病,但可读性堪比加密,review 时会被同事锤

3. 模板字符串当 case

constuid=123;switch(`user_${uid}`){case'user_123':console.log('欢迎回家');break;}

模板字符串最后算出来是'user_123',所以能进。
但同样,别把太复杂的逻辑塞进模板,否则断点都下不明白。


实战:大厂开源项目咋玩的?

光说不练假把式,我翻了三家大厂仓库,给你扒几个真·线上案例。

案例 1:React-Router 路由匹配

// 源码节选,有删改functiongetPathMatch(path){constpattern=/^\/user\/(\w+)$/;switch(true){// 注意,switch(true) 是神技casepattern.test(path):return{page:'user',id:RegExp.$1};default:returnnull;}}

这里用switch(true)强行把“正则测试”当成 case 表达式,
只要pattern.test(path)返回true,就命中。
写法很骚,但别乱学——一旦 case 多了,调试地狱

案例 2:Ant Design 把响应码翻译成文案

functionalertMessage(code){constmsg={400:'请求错误',401:'未授权',403:'禁止访问',500:'服务器炸了'}[code];switch(code){case400:case401:case403:case500:console.log(msg);break;default:console.log('未知错误');}}

这里先用对象做映射,再拿switch做兜底,既优雅又易读
如果你把case 400:写成case parseInt('400'):也能跑,但何苦呢?

案例 3:Vuex 状态机

// store/mutation-type.jsexportconstMUTATE_A='moduleA/MUTATE';exportconstMUTATE_B='moduleB/MUTATE';// store/helper.jsimport*astypesfrom'./mutation-type';functiongetHandler(type){switch(type){casetypes.MUTATE_A:return()=>console.log('A 业务');casetypes.MUTATE_B:return()=>console.log('B 业务');default:return()=>console.log('野生业务');}}

常量 + switch,让状态机一眼就能看出来漏了谁
如果直接把case 'moduleA/MUTATE':写死,重构时会哭


为啥你写的表达式总进不去?排查三步走

  1. console.log(typeof 结果)
    90% 的坑是类型不一致,比如'1' vs 1
    在 switch 前面先打印一把,确认两边类型。

  2. 确认 break 没忘
    忘了写break会 fallthrough,看起来像是进错了 case,其实是滑下去的。

  3. 严格模式 + NaN/undefined
    严格模式下,undefined变量直接抛错;
    NaN永远不等于自身,别写case NaN:自欺欺人。


让 switch 更香的四个骚技巧

技巧 1:复杂逻辑先抽到变量

// 不要这样switch(a+b*c-d){case100:...}// 建议这样constscore=a+b*c-d;switch(score){case100:...}

可读性 +10086,调试时还能直接断点看score

技巧 2:立即执行函数包裹异步?别闹

// 错误示范:IIFE 里异步,case 根本等不到结果switch((async()=>{const{type}=awaitfetchType();returntype;})()){case'VIP':...}

异步返回的是 Promise,switch 比较的是引用,永远进不去。
真要做异步判断,用 if + await,别硬塞 switch。

技巧 3:Map/Object 做兜底,比 default 更灵活

consthandler={400:()=>console.log('bad request'),401:()=>console.log('unauthorized'),500:()=>console.log('server error')};functiononError(code){(handler[code]||handler[500])();// 兜底 500}

代码行数更少,新增状态只需要改对象,不用动 switch。

技巧 4:switch(true) 虽香,别滥用

switch(true){casescore>=90:return'优秀';casescore>=60:return'及格';default:return'不及格';}

适合区间判断,但超过 3 个 case 就赶紧用 if/else 或 Map
否则 review 时会被同事问候全家。


最后一盆冷水:别为了炫技把 switch 写成谜语人

我知道,你在某篇文章看到switch (true)后惊为天人,
连夜把项目里所有if/else全改成 switch,
还顺手把 case 里塞了正则、三元、闭包、异步 Promise.all,
觉得自己帅到飞起。
但一周后,同事 review 时只想把你拉黑
代码是写给人看的,switch 只是工具,不是舞台
能一句话讲清楚的逻辑,就别让它跳芭蕾
实在忍不住想炫技,请先在注释里写 20 行道歉信
再考虑合并请求。


彩蛋:终极 cheat-sheet(直接复制到备忘录)

  1. switch 只认 ===,不认 ==。
  2. 引用类型比较地址,长得再像也没用。
  3. 函数、三元、模板字符串都能当 case,只要算出值
  4. 异步算值请左转 if/await,switch 不等人。
  5. 忘了 break 会 fallthrough,调试时别哭。
  6. NaN 永远不等于自身。
  7. 复杂表达式先抽到变量,对自己好一点
  8. 状态多就用 Map/Object,别让 switch 变成千层饼
  9. 炫技请适度,review 你的同事手里有刀

写完收工,愿你的 switch 从此不再翻车。
如果还踩到新坑,记得回来群里吐槽,我们一起骂引擎。

欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

推荐:DTcode7的博客首页。
一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身农奴把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟!


专栏系列(点击解锁)学习路线(点击解锁)知识定位
《微信小程序相关博客》持续更新中~结合微信官方原生框架、uniapp等小程序框架,记录请求、封装、tabbar、UI组件的学习记录和使用技巧等
《AIGC相关博客》持续更新中~AIGC、AI生产力工具的介绍,例如stable diffusion这种的AI绘画工具安装、使用、技巧等总结
《HTML网站开发相关》《前端基础入门三大核心之html相关博客》前端基础入门三大核心之html板块的内容,入坑前端或者辅助学习的必看知识
《前端基础入门三大核心之JS相关博客》前端JS是JavaScript语言在网页开发中的应用,负责实现交互效果和动态内容。它与HTML和CSS并称前端三剑客,共同构建用户界面。
通过操作DOM元素、响应事件、发起网络请求等,JS使页面能够响应用户行为,实现数据动态展示和页面流畅跳转,是现代Web开发的核心
《前端基础入门三大核心之CSS相关博客》介绍前端开发中遇到的CSS疑问和各种奇妙的CSS语法,同时收集精美的CSS效果代码,用来丰富你的web网页
《canvas绘图相关博客》Canvas是HTML5中用于绘制图形的元素,通过JavaScript及其提供的绘图API,开发者可以在网页上绘制出各种复杂的图形、动画和图像效果。Canvas提供了高度的灵活性和控制力,使得前端绘图技术更加丰富和多样化
《Vue实战相关博客》持续更新中~详细总结了常用UI库elementUI的使用技巧以及Vue的学习之旅
《python相关博客》持续更新中~Python,简洁易学的编程语言,强大到足以应对各种应用场景,是编程新手的理想选择,也是专业人士的得力工具
《sql数据库相关博客》持续更新中~SQL数据库:高效管理数据的利器,学会SQL,轻松驾驭结构化数据,解锁数据分析与挖掘的无限可能
《算法系列相关博客》持续更新中~算法与数据结构学习总结,通过JS来编写处理复杂有趣的算法问题,提升你的技术思维
《IT信息技术相关博客》持续更新中~作为信息化人员所需要掌握的底层技术,涉及软件开发、网络建设、系统维护等领域的知识
《信息化人员基础技能知识相关博客》无论你是开发、产品、实施、经理,只要是从事信息化相关行业的人员,都应该掌握这些信息化的基础知识,可以不精通但是一定要了解,避免日常工作中贻笑大方
《信息化技能面试宝典相关博客》涉及信息化相关工作基础知识和面试技巧,提升自我能力与面试通过率,扩展知识面
《前端开发习惯与小技巧相关博客》持续更新中~罗列常用的开发工具使用技巧,如 Vscode快捷键操作、Git、CMD、游览器控制台等
《photoshop相关博客》持续更新中~基础的PS学习记录,含括PPI与DPI、物理像素dp、逻辑像素dip、矢量图和位图以及帧动画等的学习总结
日常开发&办公&生产【实用工具】分享相关博客》持续更新中~分享介绍各种开发中、工作中、个人生产以及学习上的工具,丰富阅历,给大家提供处理事情的更多角度,学习了解更多的便利工具,如Fiddler抓包、办公快捷键、虚拟机VMware等工具

吾辈才疏学浅,摹写之作,恐有瑕疵。望诸君海涵赐教。望轻喷,嘤嘤嘤

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。愿斯文对汝有所裨益,纵其简陋未及渊博,亦足以略尽绵薄之力。倘若尚存阙漏,敬请不吝斧正,俾便精进!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1162228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从0开始学中文NLP:bert-base-chinese让文本分类更简单

从0开始学中文NLP:bert-base-chinese让文本分类更简单 1. 引言:为什么中文NLP需要专用预训练模型? 自然语言处理(NLP)在近年来取得了飞跃式发展,而预训练语言模型的出现是这一进步的核心驱动力。然而&…

5分钟部署DeepSeek-R1:本地逻辑推理引擎极速体验

5分钟部署DeepSeek-R1:本地逻辑推理引擎极速体验 1. 背景与价值定位 近年来,大模型在复杂推理任务中的表现持续突破,尤其以 DeepSeek-R1 为代表的强化学习驱动型推理模型,展现出接近人类专家的思维链(Chain of Thoug…

Claude API高效集成指南:打造智能对话应用的专业方案

Claude API高效集成指南:打造智能对话应用的专业方案 【免费下载链接】Claude-API This project provides an unofficial API for Claude AI, allowing users to access and interact with Claude AI . 项目地址: https://gitcode.com/gh_mirrors/cla/Claude-API …

GTA5增强工具YimMenu:从零开始完全配置指南

GTA5增强工具YimMenu:从零开始完全配置指南 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu 还…

如何高效转换中文数字表达?试试FST ITN-ZH大模型镜像

如何高效转换中文数字表达?试试FST ITN-ZH大模型镜像 在自然语言处理的实际应用中,我们经常面临一个看似简单却极具挑战的问题:如何将口语化、非标准的中文数字表达(如“一百二十三”、“早上八点半”)自动转换为结构…

揭秘高效OCR:如何用预置镜像快速搭建多语言文字识别服务

揭秘高效OCR:如何用预置镜像快速搭建多语言文字识别服务 你有没有遇到过这样的情况:手头有一堆不同国家的商品说明书图片,有中文、英文、日文、韩文,甚至还有俄语和法语的,但团队里没人会这些语言,更别说手…

YimMenu技术解析:从源码构建到高级防护机制实战

YimMenu技术解析:从源码构建到高级防护机制实战 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu …

证件照制作效率提升秘籍:AI智能工坊实战操作指南

证件照制作效率提升秘籍:AI智能工坊实战操作指南 1. 引言 1.1 业务场景描述 在日常办公、求职应聘、证件办理等场景中,标准证件照是不可或缺的材料。传统方式依赖照相馆拍摄或使用Photoshop手动处理,流程繁琐、耗时较长,且存在…

避坑指南:bert-base-chinese部署常见问题全解析

避坑指南:bert-base-chinese部署常见问题全解析 在自然语言处理(NLP)领域,bert-base-chinese 作为中文任务的基座模型,因其强大的语义理解能力被广泛应用于文本分类、语义匹配、命名实体识别等工业级场景。然而&#…

小白必看:一键部署fft npainting lama移除图片水印

小白必看:一键部署fft npainting lama移除图片水印 1. 引言 1.1 图像修复技术的现实需求 在数字内容爆炸式增长的今天,图像中常常包含不希望保留的元素——如水印、文字、无关物体或拍摄瑕疵。传统修图方式依赖专业软件和人工操作,耗时且对…

YimMenu完全指南:3分钟快速部署GTA5游戏增强系统

YimMenu完全指南:3分钟快速部署GTA5游戏增强系统 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu …

Open Interpreter教育领域落地:编程教学辅助部署实战

Open Interpreter教育领域落地:编程教学辅助部署实战 1. 引言 1.1 业务场景描述 在当前高校与职业培训的编程教学中,学生普遍存在“听懂了语法却写不出代码”的困境。教师面临批改作业耗时长、个性化辅导难以覆盖全体学生的挑战。传统的在线判题系统&…

YimMenu进阶指南:从功能应用到系统优化的全方位掌握

YimMenu进阶指南:从功能应用到系统优化的全方位掌握 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMen…

Linux操作系统-程序在奔跑,进程在活着:揭开计算机的“生命”奥秘

1.进程的基本概念与基本操作在一些课本上是这样描述进程的,说进程就是运行起来的程序,或者是内存中的程序。而我们的电脑中打开任务管理器,也是能看到进程的:我们可以看到,在任务管理器的左上角现实的就是进程&#xf…

DCT-Net部署避坑指南:常见错误及解决方案

DCT-Net部署避坑指南:常见错误及解决方案 1. 引言 1.1 业务场景描述 DCT-Net 是 ModelScope 平台上一个高效的人像卡通化模型,能够将真实人脸照片自动转换为风格化的卡通图像。由于其在社交娱乐、个性化头像生成、AI绘画辅助等场景中的广泛应用&#…

影视级TTS省钱方案:IndexTTS2云端按需付费,比买显卡省90%

影视级TTS省钱方案:IndexTTS2云端按需付费,比买显卡省90% 你是不是也遇到过这种情况?作为独立制片人,项目预算紧张,配音演员请不起,外包AI语音服务每分钟动辄几毛到一块钱,算下来一部短片光配音…

解锁draw.io隐藏技能:免费获取海量专业图标库的终极方案

解锁draw.io隐藏技能:免费获取海量专业图标库的终极方案 【免费下载链接】drawio-libs Libraries for draw.io 项目地址: https://gitcode.com/gh_mirrors/dr/drawio-libs 还在为draw.io有限的图标选择而苦恼?想要制作专业的网络架构图却找不到合…

MeterSphere录制插件终极指南:一键生成接口测试脚本的完整教程

MeterSphere录制插件终极指南:一键生成接口测试脚本的完整教程 【免费下载链接】chrome-extensions MeterSphere 录制浏览器请求的插件,记录浏览器中的网络请求并导出为 JMeter 或 JSON 格式的文件 项目地址: https://gitcode.com/gh_mirrors/chr/chro…

Linux基础I/O-打开新世界的大门:文件描述符的“分身术”与高级重定向

今天我们主要的内容是关于文件标识符的补充知识以及介绍重定向的相关知识,通过这篇的内容我们就能够跟深入的理解进程和文件之间的关系,以及理解我们之前可能不理解的问题。在讲解后面的内容之前,我们还是先来了解一点补充知识,是…

GTA V终极辅助工具YimMenu:从零基础到游戏高手的完整指南

GTA V终极辅助工具YimMenu:从零基础到游戏高手的完整指南 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/Y…