JavaScript 復(fù)雜判斷的更優(yōu)雅寫(xiě)法 筆記

原文:JavaScript 復(fù)雜判斷的更優(yōu)雅寫(xiě)法

正好看到這篇文章時(shí),我也思考過(guò)幾次如何簡(jiǎn)化 if else的問(wèn)題.
然后我就跟著這個(gè)又打了一遍.

他寫(xiě)的思路很清晰, 邏輯也很清晰.
后面的字符串的處理,也很腦洞大開(kāi).

不過(guò)我跟著大概打完一遍之后,
感覺(jué)還是有很多地方有疑問(wèn).

怎么說(shuō)呢, 就好像, 我隱隱約約摸到了,看到了什么東西,
但我無(wú)法用正確的概念體系去表達(dá),
而因?yàn)槲覜](méi)有這種明確的概念語(yǔ)言體系,
我想掌握起來(lái),甚至記憶起來(lái)也感覺(jué)很費(fèi)勁?

首先是這整片下來(lái),是存在一個(gè)前提的,或者適用的范圍是這樣的.
如果稍微細(xì)心一點(diǎn)就會(huì)發(fā)現(xiàn).
所有的 if 里的條件 都是 ==
而如果 == 的原始值, 也就是 布爾值, 數(shù)字,字符串,
則非常適合用 對(duì)象的形式.
因?yàn)閷?duì)象天然鍵值對(duì)形式,就包含了這種 == 的 if else

第二個(gè)問(wèn)題是維度問(wèn)題.
(天吶,我覺(jué)得科班出身的優(yōu)勢(shì)可能是擁有健全的概念體系,我特么不知道詞是不是合適啊)
我們以對(duì)象為例.
儲(chǔ)存對(duì)象有縱向維度,和橫向維度.

縱向
obj = {
    "peter" : {
       "a" : "aa" 
    },
    "mike" : {
        "a" : "bb"
    }
}
特點(diǎn)是,直接通過(guò)索引我們就可以找到值,不需要去遍歷,判斷
也許語(yǔ)義化可以更好?

橫向
obj = {
  0 : {
    master : "peter",
    type : "a",
    value : "aa"
  },
  1 : {
    master : "mike",
    type : "a",
    value : "bb"
  }, 
}
首先這種情況用數(shù)組可能更好表達(dá).
特點(diǎn)是,需要遍歷, 
相比上縱向的層級(jí)較少?
而且從某種角度來(lái)講,數(shù)據(jù)更加的豐富,
可操作的返回更多? 可擴(kuò)展性更強(qiáng)?

問(wèn)題在于, 無(wú)論是縱向還是橫向,
我們都可以認(rèn)為,多元條件時(shí),想要正確的鎖定,都需要增加維度.
要么是橫向?要么是縱向?

但這里并非是二選一, 可選的范圍很廣,
不同的數(shù)據(jù)放置方式,
可擴(kuò)展性不同,
最終調(diào)用的方式上應(yīng)該也會(huì)有所差異吧?
我暫時(shí)經(jīng)驗(yàn)少, 到底誰(shuí)跟誰(shuí)應(yīng)該在一起,
是根據(jù)數(shù)據(jù)的來(lái)源定?
還是根據(jù)數(shù)據(jù)的語(yǔ)義來(lái)定? (面向?qū)ο?)
還是根據(jù)別的什么? 常量和變量?
如果從語(yǔ)義上, 有一些維度比另一些維度要高,
那么就要體現(xiàn)出來(lái)?
比如 master 的維度,似乎比 type的維度高?
(在這個(gè)例子上完全也可以讓type的維度更高?)
怎么判斷誰(shuí)的維度更高? 根據(jù)必須有 a 才能有b 的原則?
當(dāng)然這些我現(xiàn)在是不清楚的.
甚至我可能都問(wèn)不出正確的問(wèn)題.

obj = {
 "peter" : {
    type : "a",
    value : "aaa"
  } ,
或者
  0 : [{master : "mike",type : "a"},"aa"]
}

第三個(gè)問(wèn)題是,
我們?cè)诘谝粋€(gè)問(wèn)題中說(shuō)到,
本文的適用情況基本上都是== 情況.
那么其他類(lèi)型的條件 能否轉(zhuǎn)化成 == 這種情況?
或者更直接一點(diǎn), 我們是否可以轉(zhuǎn)換成一個(gè)字符串?

其實(shí)這里是有兩種思路的.
第一種思路
我們首先回到if 的形式上

(a,b) // 參數(shù)入口
if (conditionA && conditionB) {
 function a
 function b
}

從結(jié)果上看應(yīng)該是
根據(jù) condition 和 參數(shù)(a,b) 確定 找到 相應(yīng)的 function
假設(shè)各種funciton 都放在了一個(gè)個(gè)對(duì)象里, 并且有 索引可以找到.
那么 condition 就需要 返回索引
但condition 一般是要返回布爾值, 要么false 要么 true
我們可以轉(zhuǎn)換成 根據(jù) 參數(shù) a,b 和 false true 返回一個(gè)或多個(gè)字符串?

回想策略模式,
是用一個(gè)數(shù)組,或者對(duì)象, 把所有的condition都擱置起來(lái).
不同的參數(shù)值 + 不同的condition 返回不同的 字符串(或者布爾值),
根據(jù)多個(gè)condition 返回的值(字符串或布爾值),調(diào)用相應(yīng)的函數(shù),
或者生成相應(yīng)的執(zhí)行函數(shù)放入某個(gè)數(shù)組里.

第四個(gè)問(wèn)題是,
也就是我抄寫(xiě)的這篇博文打開(kāi)我腦洞的地方.
從結(jié)果上,我們是需要一個(gè)標(biāo)記,來(lái)找到數(shù)據(jù).
而我在上面講的橫向還是縱向的前提都是,對(duì)象,或者數(shù)組.
所以才會(huì)出現(xiàn)層級(jí).

但做標(biāo)記可以用字符串.
有很多種例子
最典型的就是 JSON,嚴(yán)格來(lái)講, JSON應(yīng)該是個(gè)字符串,但可以存儲(chǔ)多種數(shù)據(jù).
比如url
REST 模式根據(jù)層級(jí)也能傳一些東西,
非REST模式 可以用 key = value 方式存數(shù)據(jù), 而這些都是數(shù)據(jù).

在這篇文章里, 他沒(méi)有把 value 變成字符串,
但是把多維度的索引,合成了一個(gè)字符串. 進(jìn)行了降維.
這就很牛逼!
而且最后用上了 正則

腦子有點(diǎn)亂.
我們開(kāi)頭說(shuō), 本篇適用的情況是 ==
也就是 一一對(duì)應(yīng)的關(guān)系, 一個(gè)索引對(duì)應(yīng)一個(gè)值(這個(gè)值可能是數(shù)據(jù),可能是函數(shù))
之后說(shuō)的是多元條件, 相當(dāng)于是 多對(duì)一.

而字符串拼接降維和正則的使用,更多的是,
設(shè)置索引?
不只可以完成多對(duì)一,
也能完成一對(duì)多. 比如通過(guò)一個(gè)字符串, 可以獲取滿足正則條件的多個(gè)數(shù)據(jù)?

我肯定把一個(gè)簡(jiǎn)單的問(wèn)題,想復(fù)雜了.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewprot" content="width=device-width, initial-scale=1.0"/>
        <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
        <title>dddd</title>
        <style type="text/css">
            
        </style>
    </head>
    <body>
         
        <script type="text/javascript">
          // 簡(jiǎn)化 if else
          // 隱藏的 if else 全都是 if else
          // 鍵值對(duì)
          // 轉(zhuǎn)化成布爾值,
          // 多元?
          // 復(fù)雜多級(jí)運(yùn)算?
          
          
          const result1 = (str) => {
            if (str == "a") {
                return "aa"
            }else if (str == "b") {
                return "bb"
            }else if (str == "c") {
                return "cc"
            }else {
              return "dd"
            }
          }
          
          
          const result2 = (str) => {
            switch (str){
              case "a":
                return "aa"
                break;
              case "b":
                return "bb"
                break;
              case "c":
                return "cc"
                break;
                
              default:
              return "dd"
                break;
            }
          }
          
          
          
          const result3 = (str) => {
            var obj = {
              "a" : "aa",
              "b" : "bb",
              "c" : "cc",
              "default" : "dd"
            }
            
            return obj[str] || obj["default"]
          }
          
          const actions = new Map([
            ["a","aa"],
            ["b","bb"],
            ["c","cc"],
            ["default","dd"]
          ])
          
          const result4 = (str) => {
            var end = actions.get(str) || actions.get("default");
            return end
          }
          
          
          
//        var end = result4('a')
//        console.log(end);
          
          // 二元條件
          
          const tResult1 = (master,str) => {
            if (master == "mike") {
                if (str == "a") {
                    return "aa"
                }else if(...){
                  ...
                }
            }else if (master == "peter") {
                if (str == "a") {
                return "aaa"
              }else if(...){
                ...
              }
            }
          }
          
          const tResult2 = (master,str) => {
            switch (master){
                case "mike":
                       switch (str){
                        case "a":
                        return "aa"
                        ...
                       }
                case "peter":
                       switch (str){
                      case "a":
                      return "aa"
                      ...
                     }
            }
          }
          // 我原來(lái)的可能的思路是這樣的
          const tResult3 = (master, str) => {
            var obj = {
              "peter" : {
                "a" : "aaa",
                "b" : "bbb",
                "c" : "ccc",
                "default" : "ddd"
              },
              "mike" : {
                "a" : "aa",
                "b" : "bb",
                "c" : "cc",
                "default" : "dd"
              }
            }
            return obj[master][str] || obj[master]["default"]
          }
          // 又或者是這樣的
          
          const tResult4 = (master, str) => {
            var arr = [
              {
                master : "peter",
                type : "a",
                value : "aaa"
              },
              {
                master : "peter",
                type : "b",
                value : "bbb"
              },
              {
                master : "peter",
                type : "c",
                value : "ccc"
              },
              {
                master : "peter",
                type : "default",
                value : "ddd"
              },
              {
                master : "mike",
                type : "a",
                value : "aa"
              },
              {
                master : "mike",
                type : "b",
                value : "bb"
              },
              {
                master : "mike",
                type : "c",
                value : "cc"
              },
              {
                master : "mike",
                type : "default",
                value : "dd"
              }
            ]
            var end1,end2;
            arr.forEach((item, index) => {
              if (item.master == master) {
                if (item.type == str) {
                     end1 = item.value
                }else if (item.type == "default"){
                   end2 = item.value
                }
               }
              })
            return end1 || end2
          }
          
          const tActions = new Map([
            [{master : 'peter',type : "a"},"aaa"],
            [{master : 'peter',type : "b"},"bbb"],
            [{master : 'peter',type : "c"},"ccc"],
            [{master : 'mike',type : "a"},"aa"],
            [{master : 'mike',type : "b"},"aa"],
            [{master : 'mike',type : "c"},"aa"]
          ])
          // 本來(lái)我對(duì) new Map() 不熟悉
          // 只知道有 get,set,has,delete
          // 沒(méi)想到 可以 用[...actions] 的方式,瞬間變成真正的數(shù)組
          // 然后就可以快樂(lè)的用數(shù)組的方法了.
          // 不過(guò)話說(shuō)回來(lái), 這個(gè)方法,壓根用的不是 new Map() 完全可以用一個(gè)數(shù)組來(lái)進(jìn)行
          // 他核心找到數(shù)據(jù)的方式,也是 filter 和 forEach..
          const tResult5 = (master, type) => {
            var action = [...tActions].filter(([item,value]) => {
              return item.master == master && item.type == type
            })
            var end;
            action.forEach(([item, value]) => {
              end = value
            })
            return end
          }
          
          var end = tResult5("mike","b");
          console.log(end);
          
          //腦洞大開(kāi)的是 字符串拼接的方式,降維.
          
          const sResult1 = (master, type) => {
            if (`${master}_${type}` == "peter_a") {
                return "aaa"
            }
            if (`${master}_${type}` == "peter_b") {
                return "bbb"
            }
            if (`${master}_${type}` == "peter_c") {
                return "ccc"
            }
            if (`${master}_${type}` == "mike_a") {
                return "aa"
            }
            if (`${master}_${type}` == "mike_b") {
                return "bb"
            }
            if (`${master}_${type}` == "mike_c") {
                return "cc"
            }
          }
          
          var end = sResult1("peter","b");
          console.log(end);
          
          const sResult2 = (master, type) => {
            let str = `${master}_${type}`;
            switch (str) {
              case "peter_a" :
                return "aaa";
              case "peter_b" :
                return "bbb";
              case "peter_c" :
                return "ccc";
              case "mike_a" :
                return "aa";
              case "mike_b" :
                return "bb";
              case "mike_c" :
                return "cc";
            }
          }
//        var end = sResult2("mike","a");
//        console.log(end);
          
          const sResult3 = (master, type) => {
            var str = `${master}_${type}`;
            let obj = {
              "peter_a" : "aaa",
              "peter_b" : "bbb",
              "peter_c" : "ccc",
              "mike_a" : "aa",
              "mike_b" : "bb",
              "mike_c" : "cc",
              "mike_default" : "dd",
              "peter_default" : "ddd"
            }
            return obj[str] || obj[`${master}_default`]
          }
            const sResult4 = (master, type) => {
            var str = `${master}_${type}`;
            let obj = {
              [/peter_[abc]/] : "aaa",// 雖然不會(huì)報(bào)錯(cuò), 但不可能得到想要的結(jié)果.該正則不起作用.
              "mike_a" : "aa",
              "mike_b" : "bb",
              "mike_c" : "cc",
              "mike_default" : "dd",
              "peter_default" : "ddd"
            }
            return obj
            return obj[str] || obj[`${master}_default`]
          }
            
//          var end = sResult4("peter","a");
//        console.log(end);
          
          const tActions3 = new Map([
            [/^mike_[abc]$/,"aa"],
            [/^peter_[abc]$/,"aaa"],
          ])
          
          const sResult5 = (master, type) => {
            var action = [...tActions3].filter(([item,value]) => {
              return item.test(`${master}_${type}`)
            })
            var end;
            action.forEach(([item,value]) => {
              end = value;
            })
            
            return end
            
            // 像上面這種,不是要執(zhí)行什么列表,而是返回值的情況可以
//          var end;
//          [...tActions3].forEach(([item, value]) => {
//            if(item.test(`${master}_${type}`)) {
//              end = value
//
//            }
//          })
//          return end
            
          }
           var end = sResult5("peter","b");
          console.log(end);
          
          
        </script>
    </body>
</html>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,329評(píng)論 2 89
  • 這周剛看完一本關(guān)于“閱讀”的書(shū),特別想推薦給大家。 這本書(shū)就是——《洋蔥閱讀法》。 誰(shuí)寫(xiě)的呢? 作者就是:簡(jiǎn)書(shū)一哥...
    易小六閱讀 1,305評(píng)論 1 29
  • 下午去圖書(shū)館還書(shū),順便去自習(xí)室看會(huì)兒書(shū),剛剛好有個(gè)離插孔進(jìn)的座位還空著,心滿意足的就坐那了順便給手機(jī)充個(gè)電還...
    你覺(jué)得啥就啥吧閱讀 196評(píng)論 0 0

友情鏈接更多精彩內(nèi)容