JS中switch内置default与switch外写默认逻辑是否完全等效
switch的default分支逻辑移到switch外部是否完全等价?
你给出的两段示例代码执行逻辑完全一致,但这是特定写法下的巧合,不是所有场景下两种写法都能等价替换,核心差异和switch的穿透(fallthrough)规则直接相关。
为什么你给的示例效果完全相同
两段代码的所有case分支都用return直接终止了函数执行:
- 当
foo.num匹配到"1"或"2"时,会直接在对应case分支返回结果,跳出函数,既不会走到default分支,也不会走到switch块后面的代码 - 当
foo.num匹配不到任何case时,第一段代码走switch内的default分支返回"neither",第二段代码跳出switch块后执行后续的return语句返回"neither",最终返回值、执行路径没有任何区别。
这种写法也是很多代码风格规范推荐的写法,可以减少一层switch块的嵌套。
两种写法存在差异的常见场景
只要不符合「所有case/default分支都有明确中断语句(return/break/throw)、default为switch最后一个分支、无穿透逻辑」的前提,两种写法就会出现逻辑偏差,最容易踩坑的是以下两种情况:
- 存在case穿透逻辑,分支未写中断语句
举个反例,以下带内部default的代码:
传入function test(foo) { let res = '' switch(foo.num) { case "1": res += "hello" default: res += "neither" case "2": res += "bye" } return res }{num: "1"}时,执行路径为case1穿透到default再穿透到case2,返回helloneitherbye;传入{num: "3"}(无匹配case)时,从default开始执行穿透到case2,返回neitherbye。
如果把default逻辑移到switch外部:
传入function test(foo) { let res = '' switch(foo.num) { case "1": res += "hello" case "2": res += "bye" } res += "neither" return res }{num: "1"}时返回hellobyeneither,传入{num: "3"}时返回neither,和原逻辑结果完全不同。 - default分支不是switch的最后一个分支
default分支的位置不影响匹配优先级,只要没有中断语句,照样会向后穿透到后续case。比如:
这段代码执行时会依次打印const x = 3 switch(x) { default: console.log('default') case 1: console.log('1') break case 2: console.log('2') }default和1,如果把default逻辑移到switch外部,x=3时只会打印default,不会执行case1的逻辑,结果完全不一致。
除此之外,如果switch写在循环内部配合continue/带标签的break使用,或者switch块内部有独立的try/catch异常捕获,两种写法的执行路径也会存在差异,不过这类场景在日常开发中出现概率极低。
日常开发中如果确定switch不存在穿透逻辑、所有分支都有明确中断,完全可以把default的兜底逻辑移到switch外部减少嵌套;但只要涉及穿透写法,就不能随意替换,否则会出现非预期的执行结果。
内容的提问来源于stack exchange,提问作者sal3jfc
相关产品推荐
相关产品推荐

