讲解
switch 处理「同一个值,多种离散取值」的分支场景:switch (表达式) 后面跟若干 case 值: 分支,命中后执行对应代码,default 处理所有未命中的情况。每个 case 末尾通常要写 break,否则程序会「穿透」——继续执行下一个 case 的代码,不管那个 case 的值匹不匹配。穿透是 switch 最常见的 bug 来源,也是最容易忘记写 break 的地方。
switch 的比较是严格相等(===),不做类型转换:case '1' 匹配不到数字 1。多个 case 共用一段逻辑时可以利用穿透特性:把几个 case 叠在一起,只在最后一个写代码和 break。另一个现代替代方案是「对象映射」:当分支只是「值到值」的翻译时,用对象字面量查表往往比 switch 更简洁,还天然没有穿透问题。
switch 和 if...else 怎么选?判断依据是条件形态:对同一个表达式做离散枚举(状态码、类型字段、命令字)用 switch 或对象映射;范围判断、复合条件、多个不同变量的组合用 if...else。代码行数差不多的情况下,对象映射 > switch > 长串 else if,可读性依次递减。
示例
function httpStatusText(code) {
switch (code) {
case 200:
return '成功';
case 301:
case 302:
return '重定向'; // 叠放 case:301 和 302 共用
case 404:
return '未找到';
case 500:
return '服务器错误';
default:
return '未知状态';
}
}
console.log(httpStatusText(200), httpStatusText(301), httpStatusText(404), httpStatusText(999));
// switch 用严格相等
switch ('1') {
case 1:
console.log('不会进来:字符串 1 不等于数字 1');
break;
default:
console.log("严格比较:'1' !== 1,落入 default");
}
// 对象映射:值到值的翻译更简洁
const roleNames = { admin: '管理员', editor: '编辑', viewer: '访客' };
function roleName(role) {
return roleNames[role] ?? '未知角色';
}
console.log(roleName('admin'), roleName('guest'));
常见坑
- 忘记 break:这是 switch 的第一大坑,穿透到下一个 case 悄悄执行,bug 隐蔽。不写 break 的 case(有意穿透)务必加注释说明。
- 以为 case 会做类型转换:case 用的是 ===,'1' 匹配不了 1,true 匹配不了 1。入参类型先统一。
- 在 case 里直接用 let/const 声明:同一个 switch 块的所有 case 共享一个块级作用域,两个 case 里各写 let x 会报重复声明。需要声明时用 { } 把 case 体包起来。
- 在需要范围判断时用 switch:switch 只能做等值匹配,score >= 90 这类条件请回到 if...else。
小结
switch 用 === 做离散匹配,case 末尾记得 break,叠放 case 可以共享逻辑;纯查表场景优先考虑对象映射。下一节开始讲循环。