JavaScript 中 switch 语句的四种进阶写法与技巧
本文深入解析 JavaScript 中 switch 语句的四种不同写法。从传统的变量匹配,到利用 === 严格相等匹配的常量 case,再到通过 IIFE(立即调用函数表达式)实现类似 C# 的 switch 表达式功能,最后介绍使用策略模式结合 find 方法的高级应用。文章通过具体代码示例,展示了如何在不同场景下优化分支逻辑,提升代码可读性与灵活性。
引言
JavaScript 中的 switch 语句其实隐藏着多种写法,你了解几种?无论你是否知晓,作者起初也只知其一。
通常我们认为 JavaScript 的 switch 只有一种标准写法,但在处理分支逻辑时,实现方式却多种多样。除了常见的 if 分支和标准的 switch 分支外,还可以采用策略模式,若将条件运算符纳入考量,恰好可以归纳为四种主要形式。
switch一般写法
本文重点探讨 switch 语句。通常大家熟悉的写法是 switch 后接变量或表达式,case 后接常量。例如,针对百分制成绩进行评级:90分及以上为优秀,80至89分为良好,60至79分为合格,60分以下为不合格。使用 switch 实现这一逻辑的大致代码如下:
function calcGrade(score) {
const line = score / 10 | 0;
switch (line) {
case 10: case 9:
return "优秀";
case 8:
return "良好";
case 7: case 6:
return "合格";
default:
return "不合格";
}
}代码中的 score / 10 | 0 与 Math.floor(score / 10) 效果一致,均是通过除以 10 后取整数部分来实现分级。
这种 switch 用法中规中矩,通过取整技巧避免了冗长的 if...else 分支判断,算是一种巧妙的实现方式。
然而,如果规则发生变化,例如将合格与良好的分界线从 80 分下调至 75 分,该如何调整?
按上面取整的办法依然可以,不过这次除数不再是 10,而是 5。相应地,case 也多了很多:
- 18、19、20 对应优秀
- 15、16、17 对应良好
- 12、13、14 对应合格
- 其余情况为不合格
编写多达 9 个 case 显然繁琐,此时使用 if...else 可能更为合适。
switch简单写法
真的如此吗?其实 switch 还有更简洁的写法:
function calcGrade(score) {
switch (true) {
case score >= 90:
return "优秀";
case score >= 75:
return "良好";
case score >= 60:
return "合格";
default:
return "不合格";
}
}这种写法看似反常,并非习惯中的 switch 变量匹配 case 常量,而是 switch 常量匹配 case 表达式。运行这段代码会发现其完全正常,原因在于 switch 和 case 实际上是按照 ===(严格相等)进行匹配的。switch 和 case 后均可接表达式,并不局限于常量。
没错,就是表达式。
因此,在上述示例中,将 switch(true) 替换为 switch( 2 > 1) 也能达到相同的效果。
思路已打开。switch 究竟有多少种写法已不再重要,接下来我们将探讨 switch 的变体应用。
IIFE 封装
看到 C# 拥有 switch 表达式功能,是否心生羡慕?JavaScript 中能否实现?
无需羡慕,在 JavaScript 中一切皆可为表达式;若不能,通过 IIFE(立即调用函数表达式)封装即可实现。
function calcGrade(score) {
return (value => {
switch (true) {
case value >= 90:
return "优秀";
case value >= 75:
return "良好";
case value >= 60:
return "合格";
default:
return "不合格";
}
})(score);
}注意此处将 score 作为 IIFE 的参数传入,因为在实际使用中,传入的往往是一个表达式。这种情况下应提前求值且仅求值一次,以避免潜在的副作用。
封成策略
然而,仅如此封装意义不大。若需进一步封装,可将其转化为策略模式:
function calcGrade(score) {
return ((value, rules) => rules.find(({ t }) => t(value)).v)(
score,
[
{ t: n => n >= 90, v: "优秀" },
{ t: n => n >= 75, v: "良好" },
{ t: n => n >= 60, v: "合格" },
{ t: () => true, v: "不合格" },
]
);
}每个策略对象包含一个测试器(t)和一个返回值(v)。测试器是一个判断函数,接收待判断的值,即 switch (表达式) 中的表达式。该表达式在作为 IIFE 参数传入前已提前求值。应用策略的过程简单直接:找到第一个符合条件的策略,并提取其对应的值。
当然,对于简单场景使用策略模式略显繁琐。在真正需要策略模式的场景中,策略通常包含一个行为(即函数),而不仅仅是一个值。
我们知道,在标准 switch 语句中,所有 case 处于同一作用域,因此不能在不同 case 中声明同名的局部变量。虽然使用 { }(块级作用域)包裹可以解决此问题,但代码可读性较差,且容易遗漏 break(break)。若采用策略模式,代码结构会更清晰,且无需担心 break 的问题:
此处为了演示,策略行为中先输出成绩,再返回等级。
function calcGrade(score) {
return ((value, rules) => rules.find(({ t }) => t(value)).fn(value))(
score,
[
{
t: n => n >= 90,
fn: score => {
const grade = "优秀";
console.log(grade, score);
return grade;
}
},
{
t: n => n >= 75,
fn: score => {
const grade = "良好";
console.log(grade, score);
return grade;
}
},
{
t: n => n >= 60,
fn: score => {
const grade = "合格";
console.log(grade, score);
return grade;
}
},
{
t: () => true,
fn: score => {
const grade = "不合格";
console.log(grade, score);
return grade;
}
},
]
);
}代码长度有所增加,因为包含了策略行为的逻辑。若将 switch 视为表达式使用,策略部分应尽可能简洁。上述代码中策略行为相似,可封装为一个函数,从而写成表达式形式:
function calcGrade(score) {
const printGrade = (grade, score) => {
console.log(grade, score);
return grade;
};
return ((value, rules) => rules.find(({ t }) => t(value)).fn(value))(
score,
[
{ t: n => n >= 90, fn: score => printGrade("优秀", score) },
{ t: n => n >= 75, fn: score => printGrade("良好", score) },
{ t: n => n >= 60, fn: score => printGrade("合格", score) },
{ t: () => true, fn: score => printGrade("不合格", score) },
]
);
}现在看起来是否更加规范?
上述代码形式各异,但核心功能相似,并无绝对的优劣之分。顺眼的写法即优雅,反之则不然。根据具体场景选择合适的方法即可。上述代码使用 find() 来查找策略,若改用 filter(),则呈现另一种景象。
以上就是 JavaScript 中 switch 四种写法的详细内容,更多关于 JS switch 写法的资料请持续关注本站相关文章!
JavaScript异步发送HTTP请求时怎么优雅地处理错误
2026-11-05 17:10:44
5款主流JS在线运行工具对比:CodePen、JSFiddle与StackBlitz怎么选
2026-11-05 17:04:04
JavaScript入门书籍避坑:这些书不适合初学者
2026-11-05 16:31:15
JS使用Math.round实现保留两位小数的原理与代码
2026-11-05 15:35:55
JavaScript 原生 Date 对象怎么实现日期加减
2026-11-05 14:30:00
