<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          switch 有四樣寫法你知道么

          共 11544字,需瀏覽 24分鐘

           ·

          2022-07-05 17:49

          本期為大家推薦的是社區(qū)作者 邊城 的文章 ,在這篇文章中邊城大大為大家介紹了 switch 的幾種寫法,快來看看你會幾種呀?


          話不多說,馬上進入正文學習啦!


          JavaScript 的 switch 有四樣寫法,你知道么?不管你知道不知道,反正我是不知道。


          我所知道的 JavaScript 的 switch 語句只有一種寫法。但要說到對分支的處理,寫法可就多了去了。if 分支寫法可以算一種,switch 分支寫法可以算第二種,第三種是使用策略模式,如果要把條件運算符也算上的話,嗯,剛好四種。


          不過本文的主角是 switch。大家都了解 switch 的寫法一般來說是 switch 變量或表達式,case 常量。嗯,比如說,一個百分制成績,90 及 90 分以上算優(yōu)秀,80 及以上 90 以下算良好,60 及以上 80 以下算合格,60 以下為不合格,用 switch 大概會這么寫:


          function calcGrade(score) {
              const line = score / 10 | 0;
              switch (line) {
                  case 10: case 9:
                      return "優(yōu)秀";
                  case 8:
                      return "良好";
                  case 7: case 6:
                      return "合格";
                  default:
                      return "不合格";
              }
          }


          代碼中 score / 10 | 0  Math.floor(score / 10) 是一樣的效果,就是除以 10 取商的整數(shù)部分。


          這段 switch 用得中規(guī)中矩,用取整的辦法來避免使用一長串 if ... else 分支也算是取了巧。


          但是現(xiàn)在規(guī)則改了,將合格和良好的分隔點從 80 分降到 75 分,該怎么辦?


          按上面取整的辦法依然可以,不過這次除數(shù)不再是 10,而是 5。相應地,case 也多了很多:


          • 18、19、20 是優(yōu)秀
          • 15、16、17 是良好
          • 12、13、14 是合格
          • 剩下的是不合格

          寫 9 個 case,真不如用 if ... else 算了。

          是嗎?其實用 switch 也有簡單一些的寫法:

          function calcGrade(score) {
              switch (true) {
                  case score >= 90:
                      return "優(yōu)秀";
                  case score >= 75:
                      return "良好";
                  case score >= 60:
                      return "合格";
                  default:
                      return "不合格";
              }
          }

          是不是感覺有些奇怪?這完全不是習慣了的 switch 表達式 case 常量,而是正好相反,switch 常量 case 表達式!如果你拿這段程序去跑一下,會發(fā)現(xiàn)一點問題都沒有。因為——switch case 是按 === 來匹配的,它并不在乎是表達式還是常量,或者說,switch 和 case 后面都可以接表達式!

          是的,表達式!

          所以上面那個示例中,把 switch(true) 改成 switch( 2 > 1) 也是一樣的效果。

          好啦,腦洞已開。switch 到底有多少種寫法已經(jīng)不重要了。接下來要研究的是 switch 的變種 ——

          看到 C# 有 switch 表達式,眼饞,能實現(xiàn)嗎?

          不用眼饞,JavaScript 里一切都可以是表達式 …… 如果不是,用 IIFE 封裝一個就是了

          function calcGrade(score) {
              return (value => {
                  switch (true) {
                      case value >= 90:
                          return "優(yōu)秀";
                      case value >= 75:
                          return "良好";
                      case value >= 60:
                          return "合格";
                      default:
                          return "不合格";
                  }
              })(score);
          }

          注意這里把 score 作為 IIFE 的參數(shù),是因為在實際使用中,可能需要傳入的是一個表達式。這種情況下應該提前求值,而且只求一次(避免替在的副作用)。

          不過這樣的封裝顯然沒什么意義,如果真要這樣封裝,不如封成策略:

          function calcGrade(score) {
              return ((value, rules) => rules.find(({ t }) => t(value)).v)(
                  score,
                  [
                      { t: n => n >= 90, v: "優(yōu)秀" },
                      { t: n => n >= 75, v: "良好" },
                      { t: n => n >= 60, v: "合格" },
                      { t: () => true, v: "不合格" },
                  ]
              );
          }

          每項策略都是一個含有 tester (t) 和值 (v) 的對象。tester 是一個判斷函數(shù),傳入需要判斷的值,也就是 switch (表達式) 這里表達式,而這個表達式也是提前求值之后作為 IIFE 的參數(shù)傳入的。應用策略的過程簡單粗暴,就是找到第一個符合條件的策略,把它的值取出來。

          當然這樣用策略有點大材小用。真正需要用策略的情況,策略中通常不是一個值,而是一個行為,也就函數(shù)。

          我們知道在 switch 語句中,各個 case 之間是在同一個作用域內(nèi),所以不能在兩個 case 語句中聲明同一個局部變量。雖然用 { } 包裹可以解決這些問題,但代碼看起來不怎么好看,特別是還要注意不要忘了 break。如果用策略的話,看起來可能會順眼一眼,也不用擔心 break 的問題:

          這里為了演示,在策略行為中將先輸出成績,再返回等級。

          function calcGrade(score) {
              return ((value, rules) => rules.find(({ t }) => t(value)).fn(value))(
                  score,
                  [
                      {
                          t: n => n >= 90,
                          fn: score => {
                              const grade = "優(yōu)秀";
                              console.log(grade, score);
                              return grade;
                          }
                      },
                      {
                          t: n => n >= 75,
                          fn: score => {
                              const grade = "良好";
                              console.log(grade, score);
                              return grade;
                          }
                      },
                      {
                          t: n => n >= 60,
                          fn: score => {
                              const grade = "合格";
                              console.log(grade, score);
                              return grade;
                          }
                      },
                      {
                          t: () => true,
                          fn: score => {
                              const grade = "不合格";
                              console.log(grade, score);
                              return grade;
                          }
                      },
                  ]
              );
          }

          代碼確實有點長,因為有策略行為邏輯在里面。如果真的是要當作 switch 表達式來用的話,策略部分應該是一個表達式,不會太長的。上面的代碼中,策略行為相似,可以封裝成一個函數(shù),這樣就能寫成表達式的形式了:

          function calcGrade(score) {
              const printGrade = (grade, score) => {
                  console.log(grade, score);
                  return grade;
              };

              return ((value, rules) => rules.find(({ t }) => t(value)).fn(value))(
                  score,
                  [
                      { t: n => n >= 90, fn: score => printGrade("優(yōu)秀", score) },
                      { t: n => n >= 75, fn: score => printGrade("良好", score) },
                      { t: n => n >= 60, fn: score => printGrade("合格", score) },
                      { t: () => true, fn: score => printGrade("不合格", score) },
                  ]
              );
          }

          現(xiàn)在看起來是不是像樣了?

          上面的代碼形式各異,干的事情都差不多,也沒有誰優(yōu)誰劣的比較??吹庙樠墼趺炊純?yōu)雅,看不順眼怎么都不受寵。在不同的情況下,選用合適的做法就好。上面的代碼使用的 find() 來查找策略,如果改用 filter(),那又會是另一番景象了 ~(~ ̄▽ ̄)~。



          SegmentFault 思否社區(qū)小編說


          自 2022-07-01 起 SegmentFault 思否公眾號改版啦!之后將陸續(xù)推出新的欄目和大家見面?。ㄕ埵媚恳源絶?


          在「社區(qū)精選」欄目中,我們將為廣大開發(fā)者推薦來自 SegmentFault 思否開發(fā)者社區(qū)的優(yōu)質(zhì)技術(shù)文章,這些文章全部出自社區(qū)中充滿智慧的技術(shù)創(chuàng)作者哦!


          希望通過這一欄目,大家可以共同學習技術(shù)干貨,GET 新技能和各種花式技術(shù)小 Tips。


          歡迎越來越多的開發(fā)者加入創(chuàng)作者的行列,我們將持續(xù)甄選出社區(qū)中優(yōu)質(zhì)的內(nèi)容推介給更多人,讓閃閃發(fā)光的技術(shù)創(chuàng)作者們走到聚光燈下,被更多人認識。


          「社區(qū)精選」投稿郵箱:[email protected]

          投稿請附上社區(qū)文章地址





          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,公眾號后臺回復“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 32
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美操片在线观看 | 日韩视频高清无码 | 欧美色逼| 免费播放婬乱男女婬视频国产 | 欧美亚洲日韩一区二区 |