淺析switch

来源:http://www.cnblogs.com/xiaojing-yjt/archive/2017/08/29/7447686.html
-Advertisement-
Play Games

先聲明下:本文中的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的理解,如果有什麼寫得不對的地方,歡迎大家指正!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ImageData對象 ImageData對象包含了一個區域內的canvas的像素信息。它包含以下可讀屬性: width canvas的寬度,單位是像素。 height canvas的高度,單位是像素。 data 一個Uint8ClampedArray的一維數組,包含了每個像素的RGBA值。 什麼是 ...
  • 一個函數可以看成一個類,原型是所有類都有的一個屬性,原型的作用就是給這個類的每一個對象都添加一個統一的方法 <script> //聲明一個類 function Person(name,age) { this.name=name; this.age=age; } //使用原型給類添加方法 Person ...
  • javascript中如何實現繼承 ...
  • 對象和變數的區別 假如你叫張三,“變數”和“對象”的區別就是“張三”和“你”的區別 再比如: Var st = [40,25]; 上述的完整版是: Var st =new Array(); St[0]=40; St[1]=25; 這意思是將一個數組類型的對象賦值給一個var類型的變數。也可以理解為v ...
  • 我們一般使用webpack熱載入開發SPA應用,但工作中難免會遇到一些多頁面的demo或項目。 故參考 kingvid-chan 的代碼,搭了一個使用HRM開發多頁面web應用的腳手架,剛好也進一步學習webpack。 項目結構很簡單,需要註意的是: 因使用fs等api,所以每次添加新頁面之後,需要 ...
  • [1]效果演示 [2]功能分析 [3]靜態時鐘 [4]動態效果 [5]完整代碼 ...
  • var csns=document.getElementById("csns"); var tcx=csns.getContext("2d"); csns.style.border="1px red solid"; tcx.strokeStyle="#1296DB" tcx.beginPath();... ...
  • router.js html: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...