先聲明下:本文中的switch僅限於JS,我並未查閱過其他編程語言中switch的語法,但有朋友反映在OC中並不適用! 一、switch語句基礎概念 屬於選擇結構,一般用於選擇要執行的多個代碼塊之一。 基本語法 工作原理:首先設置表達式 ,通常是一個變數。隨後表達式的值會與結構中的每個 case 的 ...
先聲明下:本文中的switch僅限於JS,我並未查閱過其他編程語言中switch的語法,但有朋友反映在OC中並不適用!
一、switch語句基礎概念
屬於選擇結構,一般用於選擇要執行的多個代碼塊之一。
基本語法
switch(expression) {
case value1: 執行代碼塊 1 break; case value2: 執行代碼塊 2 break; default: 表達式,與 case 1 和 case 2 不同時執行的代碼 }
工作原理:首先設置表達式 ,通常是一個變數。隨後表達式的值會與結構中的每個 case 的值做比較。如果存在匹配,則與該 case 關聯的代碼塊會被執行。可以使用break來阻止代碼向下一個case執行。
二、switch的應用
好的,根據以上的概念,switch可以用於對錶達式的值進行簡單判斷,並執行不同情況的代碼塊。
例如以下這種簡單的情況:
1 //判斷今天是星期幾 2 3 var day=new Date().getDay(); 4 5 switch (day) 7 { 9 case 0: 11 x="Today it's Sunday"; 13 break; 15 case 1: 17 x="Today it's Monday"; 19 break; 21 case 2: 23 x="Today it's Tuesday"; 25 break; 27 case 3: 29 x="Today it's Wednesday"; 31 break; 33 case 4: 35 x="Today it's Thursday"; 37 break; 39 case 5: 41 x="Today it's Friday"; 43 break; 45 case 6: 47 x="Today it's Saturday"; 49 break; 51 }
看起來,並沒有if語句用著方便。因為,似乎case只能設置常量,對範圍值的判斷並沒有if語句出色,但是請看下麵的例子:
1 var num = parseInt(window.prompt('輸入成績')); 2 3 switch(true) 5 { 7 case num>=90 && num<=100: 8 9 alert('A'); 11 break; 12 13 case num>=80 && num<90: 14 15 alert('B'); 17 break; 18 19 default: 20 21 alert('C'); 23 break; 25 }
這個例子或許會讓人心生疑惑,為什麼case後又能設置表達式呢,而且可以正確判斷呢,這又必須從switch的工作原理開始說起。
三、switch的工作原理
先回顧一下switch的工作原理:
首先設置表達式 ,通常是一個變數。隨後表達式的值會與結構中的每個 case 的值做比較。如果存在匹配,則與該 case 關聯的代碼塊會被執行。可以使用break來阻止代碼向下一個case執行。
這段話摘自w3school關於switch的介紹,原文並沒有什麼問題,但是我們經常忽略的一個地方是 case 的值!在《JavaScript高級程式設計》一書中,對 case 的定義是value(值),這也很容易讓人誤解為一個常量,當然,書中也介紹了 case 用表達式的情況,但卻並未具體說明。
那麼,case到底可以設置什麼呢?其實,查閱ECMA後,一切就很清楚了:
switch(Expression) CaseBlock
CaseClause:case Expression:
Return Normal Completion(empty).
CaseClause:case Expression:StatementList
Return the result of evaluating StatementList.
DefaultClause:default:
Return Normal Completion(empty).
DefaultClause:default:StatementList
Return the result of evaluating StatementList.
摘自——ECMA-262
先不管那些看不明白的英文,鎖定一個關鍵詞“Expression”——表達式,這下就清楚了, case 後面也可以跟表達式!
現在,讓我們再梳理一次switch的工作原理:
1.switch(expression)先獲取expression的值作為引用;
2.逐個case遍歷,計算表達式,表達式的值並不會影響switch判斷的基準,因為第一步已經獲取了引用;
3.若匹配case,就執行匹配case的代碼塊,若帶終止(如break)的話,就停止遍歷剩下的case。
4.若無匹配的case,case將全部遍歷一遍。
知道了工作原理,讓我們再來看看上一個例子:
1 var num = 70; 2 3 switch(true) //引用true的值 5 { 7 case num>=90 && num<=100: //遍歷case1,計算表達式,表達式值為false,兩個值不全等,繼續遍歷下一項 9 alert('A'); 11 break; 13 case num>=80 && num<90: //遍歷case2,計算表達式,表達式值為false,兩個值不全等,繼續遍歷下一項 14 alert('B'); 15 break; 16 default: //以上case都不滿足,執行此處代碼塊 18 alert('C'); 20 break; 22 } 23 24 //執行結果: alert('C');
講到這裡,相信大家對switch有更深入了理解了,或許可以試試下麵的例子:
1 var num = 4; 2 3 switch (num) 5 { 7 case num = 1: 9 alert("1"); 11 break; 13 case num = 1: 15 alert("1"); 17 break; 19 case num = 3: 21 alert("3"); 23 break; 25 default: 27 alert("以上都不執行"); 29 alert(num); 31 break; 33 } 36 37 //執行結果:以上都不執行,3
咦,為什麼會執行default中的代碼呢,在case1中,num被賦值為1了,那麼num值與case2相等,應該執行case2中的代碼呀?其實,再往上翻翻,看看switch的工作原理的第一句:switch(expression)先獲取expression的值作為引用。
這表示,switch是引用num的值,所以在接下來case中,對num賦值的操作並不會影響switch在第一步中的引用值。
上一道例題的工作原理就可以解析為下麵幾步了:
1、引用num的值:4;
2、遍歷case1,計算表達式,表達式num被賦值為1,兩個值不全等,繼續遍歷下一項;
此處,num值被重新賦值為1後,switch判斷的基準值依然是4,因為判斷基準是引用自num的值,在第一步已經獲取了引用,所以在接下來的遍歷中,case中對num的賦值操作,並不會影響switch的判斷基準值;
3、遍歷case2,計算表達式,表達式num被賦值為1,兩個值不全等,繼續遍歷下一項;
4、遍歷case2,計算表達式,表達式num被賦值為3,兩個值不全等,繼續遍歷下一項;
5、以上結果都不匹配,執行此處代碼,此時,num的值為3。
OK,寫到這裡,大家應該對switch有了一定的理解,如果還想更深入的瞭解switch,建議去學習ECMA的相關資料!
結束語
這是JS菜鳥——本人對switch的理解,如果有什麼寫得不對的地方,歡迎大家指正!