原文:The Switch/Case Statement in JavaScript
switch
语句就像多个叠加的if语句,可以在不同条件执行不同的代码。本文展示了如何使用switch/case
语句。
switch
语句计算一个表达式,计算结果等于某个case
的值时,就会执行这个case
的语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const hero = 'Batman'; let sidekick;
switch (hero) { case 'Batman': sidekick = 'Robin'; break; case 'Aquaman': sidekick = 'Aqualad'; break; case 'Superman': sidekick = 'Jimmy Olsen'; break; default: throw new Error('Unknown hero'); }
sidekick;
|
一定别忘了在语句块后加break
!如果在case
语句块最后没有break
,JavaScript会继续执行下一个case
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| const hero = 'Batman'; let sidekick;
switch (hero) { case 'Batman': sidekick = 'Robin'; case 'Aquaman': sidekick = 'Aqualad'; break; case 'Superman': sidekick = 'Jimmy Olsen'; break; default: throw new Error('Unknown hero'); }
sidekick;
|
这个语言特点也有一些妙用,可以多个case
条件执行同一个语句块。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const sidekick = 'Nightwing'; let hero;
switch (sidekick) { case 'Robin': case 'Nightwing': case 'Bluebird': hero = 'Batman'; break; case 'Aqualad': case 'Tempest': hero = 'Aquaman'; break; default: throw new Error('Unknown sidekick'); }
hero;
|
相等检查
switch
语句先计算给定表达式的值,然后用严格相等来比较每个case
的值。以下if
语句在功能上与第一个例子是等效的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const hero = 'Batman'; let sidekick;
if (hero === 'Batman') { sidekick = 'Robin'; } else if (hero === 'Aquaman') { sidekick = 'Aqualad'; } else if (hero === 'Superman') { sidekick = 'Jimmy Olsen'; } else { throw new Error('Unknown hero'); }
sidekick;
|
因为switch
语句使用严格相等,要比较对象时要注意做好类型转换,例如日期或MongoDB的ObjectId。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| const date = new Date('2020/07/04'); let holiday;
const goodFriday = new Date('2020/04/10'); const independenceDay = new Date('2020/07/04'); const christmas = new Date('2020/12/25');
date === independenceDay;
switch (date.getTime()) { case goodFriday.getTime(): holiday = 'Good Friday'; break; case independenceDay.getTime(): holiday = 'Independence Day'; break; case christmas.getTime(): holiday = 'Christmas'; break; }
holiday;
|
替代方案
除了路过式的case
语句,其他情况都可以用if语句来替代switch/case
。另一种替代方案是定义一个对象或Map,以case
条件作为key,包含对应的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const hero = 'Batman'; let sidekick;
const obj = { 'Batman': () => { sidekick = 'Robin'; }, 'Aquaman': () => { sidekick = 'Aqualad'; }, 'Superman': () => { sidekick = 'Jimmy Olsen'; } };
if (obj.hasOwnProperty(hero)) { obj[hero](); }
sidekick;
|
用对象实现的条件分支,优势是能以编程方式构建对象。如果switch
语句有点重复冗长,可以考虑用for
循环,构建一个条件分支的对象。
建议
switch
语句有许多不直观之处,例如意外的跳到下一个case
语句。ESLint有一个no-fallthrough
规则,可以在lint层规避这个问题。然而,大部分情况下if/else
语句或对象条件都是更好的选择,因为switch
比较少见,大多数人对switch
的语义不敏感。