switch
語句可以替代多個 if
判斷。
switch
語句爲多分支選擇的情況提供了壹個更具描述性的方式。
switch
語句有至少壹個 case
代碼塊和壹個可選的 default
代碼塊。
就像這樣:
switch(x) { case 'value1': // if (x === 'value1') ... [break] case 'value2': // if (x === 'value2') ... [break] default: ... [break] }
比較 x
值與第壹個 case
(也就是 value1
)是否嚴格相等,然後比較第二個 case
(value2
)以此類推。
如果相等,switch
語句就執行相應 case
下的代碼塊,直到遇到最靠近的 break
語句(或者直到 switch
語句末尾)。
如果沒有符合的 case,則執行 default
代碼塊(如果 default
存在)。
switch
的例子(高亮的部分是執行的 case
部分):
let a = 2 + 2; switch (a) { case 3: alert( 'Too small' ); break; case 4: alert( 'Exactly!' ); break; case 5: alert( 'Too big' ); break; default: alert( "I don't know such values" ); }
這裏的 switch
從第壹個 case
分支開始將 a
的值與 case
後的值進行比較,第壹個 case
後的值爲 3
匹配失敗。
然後比較 4
。匹配,所以從 case 4
開始執行直到遇到最近的 break
。
如果沒有 break
,程序將不經過任何檢查就會繼續執行下壹個 case
。
無 break
的例子:
let a = 2 + 2; switch (a) { case 3: alert( 'Too small' ); case 4: alert( 'Exactly!' ); case 5: alert( 'Too big' ); default: alert( "I don't know such values" ); }
在上面的例子中我們會看到連續執行的三個 alert
:
alert( 'Exactly!' ); alert( 'Too big' ); alert( "I don't know such values" );
任何表達式都可以成爲 switch/case
的參數
switch
和 case
都允許任意表達式。
比如:
let a = "1"; let b = 0; switch (+a) { case b + 1: alert("this runs, because +a is 1, exactly equals b+1"); break; default: alert("this doesn't run"); }
這裏 +a
返回 1
,這個值跟 case
中 b + 1
相比較,然後執行對應的代碼。
共享同壹段代碼的幾個 case
分支可以被分爲壹組:
比如,如果我們想讓 case 3
和 case 5
執行同樣的代碼:
let a = 3; switch (a) { case 4: alert('Right!'); break; case 3: // (*) 下面這兩個 case 被分在壹組 case 5: alert('Wrong!'); alert("Why don't you take a math class?"); break; default: alert('The result is strange. Really.'); }
現在 3
和 5
都顯示相同的信息。
switch/case
有通過 case 進行“分組”的能力,其實是 switch 語句沒有 break
時的副作用。因爲沒有 break
,case 3
會從 (*)
行執行到 case 5
。
強調壹下,這裏的相等是嚴格相等。被比較的值必須是相同的類型才能進行匹配。
比如,我們來看下面的代碼:
let arg = prompt("Enter a value?") switch (arg) { case '0': case '1': alert( 'One or zero' ); break; case '2': alert( 'Two' ); break; case 3: alert( 'Never executes!' ); break; default: alert( 'An unknown value' ) }
在 prompt
對話框輸入 0
、1
,第壹個 alert
彈出。
輸入 2
,第二個 alert
彈出。
但是輸入 3
,因爲 prompt
的結果是字符串類型的 "3"
,不嚴格相等 ===
于數字類型的 3
,所以 case 3
不會執行!因此 case 3
部分是壹段無效代碼。所以會執行 default
分支。
重要程度: 5
將下面 switch
結構的代碼寫成 if..else
結構:
switch (browser) { case 'Edge': alert( "You've got the Edge!" ); break; case 'Chrome': case 'Firefox': case 'Safari': case 'Opera': alert( 'Okay we support these browsers too' ); break; default: alert( 'We hope that this page looks ok!' ); }
爲了精確實現 switch
的功能,if
必須使用嚴格相等 '==='
。
對于給定的字符串,壹個簡單的 '=='
也可以。
if(browser == 'Edge') { alert("You've got the Edge!"); } else if (browser == 'Chrome' || browser == 'Firefox' || browser == 'Safari' || browser == 'Opera') { alert( 'Okay we support these browsers too' ); } else { alert( 'We hope that this page looks ok!' ); }
請注意:將 browser == 'Chrome' || browser == 'Firefox' …
結構分成多行可讀性更高。
但 switch
結構更清晰明了。
重要程度: 4
用 switch
重寫以下代碼:
let a = +prompt('a?', ''); if (a == 0) { alert( 0 ); } if (a == 1) { alert( 1 ); } if (a == 2 || a == 3) { alert( '2,3' ); }
前兩個檢查爲前兩個 case
,第三個檢查分爲兩種情況:
let a = +prompt('a?', ''); switch (a) { case 0: alert( 0 ); break; case 1: alert( 1 ); break; case 2: case 3: alert( '2,3' ); break; }
請注意:最後的 break
不是必須的。但是爲了讓代碼可擴展我們要把它加上。
有可能之後我們想要再添加壹個 case
,例如 case 4
。如果我們忘記在它之前添加壹個 break,那麽在 case 3 執行結束後可能會出現錯誤。所以這是壹種自我保險。