前言es6
做爲搬磚在第一線的底層工人,業務場景歷來是沒有作不到只有想不到的複雜。數組
不過他強任他強,if-else全搞定,搬就完了。可是隨着業務迭代或者項目交接,本身在看本身或者別人的if代碼的時候,心情就再也不表述了,各自深有體會。因此咱們一塊兒看看if還能怎麼寫數據結構
最基本if-else分佈式
假設有這麼個場景,不一樣狀況下打印不一樣值。函數
由於涉及到的條件太多,就不提三目運算之類優化了。微服務
if (a == 1) {源碼分析
console.log('a1')性能
} else if (a == 2) {學習
console.log('b2')優化
} else if (a == 3) {
console.log('c3')
} else if (a == 4) {
console.log('d4')
}
/* n..... */
如今還算能看,由於邏輯簡單,若是邏輯複雜,迭代多個版本以後,你還敢動嗎。
每動一下就戰戰兢兢,誰知道哪裏會遺漏。
那麼換種方式呢
switch-case
這樣稍微清晰那麼一點,差異好像沒什麼差異:
switch(a){
case 1:
console.log('a1');
break;
/* 省略。。。 */
case 40:
console.log('a40');
break;
}
分離配置信息與執行動做
object映射
定義一個object做爲配置對象來存放不一樣狀態,經過鏈表查找
const statusMap = {
1:()=>{
console.log('a1')
},
2:()=>{
console.log('b2')
}
/* n.... */
}
// 執行
let a = 1
statusMap[a || 1]()
這樣比較清晰,將條件配置與具體執行分離。若是要增長其餘狀態,只修改配置對象便可。
數組映射
固然在某些狀態下可使用數組,來作這個配置對象。
// 這裏就涉及其餘優化了,例如將執行函數抽離出來,你們不要關注func的內容就好。
// 它就是個function,內容很複雜
const statusArr = [function(){
console.log(1)
},
function () {
console.log(2)
},]
// 執行
let a = 1
statusArr[a || 1]()
數組的要求更高一點,若是是其餘key,例如字符串,那麼數組就不能知足需求了
升級版:不一樣key相同value
這樣看起來好一點了,那麼需求又有變更了,
前面是每種處理方式都不一樣,下面有幾種狀況下處理函數相同的,例如1-39的時候,調用a,40以後調用b,若是咱們繼續來用映射的方式來處理。
function f1 (){
console.log(1)
}
function f2 (){
console.log(2)
}
const statusMap={
1:f1,
2:f1,
3:f1,
4:f1,
//省略
40:f2
}
let a = 2
statusMap[a]()
這樣固然也能夠,不太重複寫那麼多f1,代碼看起來不夠簡潔。
開始重構以前咱們先捋一下思路,無非是想把多個key合併起來,對應一個value。也就是說咱們的鍵值不是字符串而是個數組,object顯然只支持字符串,那麼能夠將這麼多key合併成一個:'1,2,3,4,..,9'。
可是查找的時候有點問題了,咱們的參數確定不能徹底匹配。
接着走下去,是否是作個遍歷加個判斷,包含在子集內的都算匹配,那麼代碼看起來就是下面這個樣子。
// 將鍵值key設置爲一個拼接以後的字符串
const statusMap = {
'1,2,3,4,5': f1,
//省略
40: f2
}
// 獲取全部的鍵值,待會遍歷用
const keys = Object.keys(statusMap),
len = keys.length
// 遍歷獲取對應的值
const getVal=(param='')=>{
// 用for循環的緣由在於匹配以後就不須要繼續遍歷
for (let i = 0; i < len; i++) {
const key = keys[i],
val = statusMap[key]
// 這裏用什麼來判斷就隨便了,兩個字符串都有。
if (key.includes(param)) {
return val
}
}
}
let a = 2,
handle = getVal(a)
handle() // 1
可是這樣來看,增長了個遍歷的過程,並且是拼接字符串,萬一哪天傳了個逗號進來,會獲得了預料以外的結果。
map
es6有個新的數據結構Map,支持任意數據結構做爲鍵值。若是用Map可能更清晰一點。
/**
* map鍵值索引的是引用地址,
* 若是是下面這樣的寫法很差意思,永遠得不到值
* map1.set([1,4,5],'引用地址')
* map1.get([1,4,5]) //輸出爲undefined
* 就像直接訪問
* map1.get([1,2,3,4,5]) //一樣爲undefined
*/
const map1 = new Map()
const statusArr = [1,2,3,4,5]
map1.set(statusArr,f1)
// 預設默認值,由於不能直接遍歷
let handle = function(){}
const getVal = (param = '') => {
for (let value of map1.entries()) {
console.log(JSON.stringify(value))
if (value[0].includes(param)){
console.log(value)
// 不能跳出 只能處理了
handle = value[1]
}
}
}
const a = 2
getVal(a)
handle()
我的而言雖然這樣減小了重複代碼,可是又增長了一步匹配值的操做,優劣就見仁見智吧。
雙數組
確定有部分人就是不想作遍歷的操做,既然一個數組不能知足,那麼兩個數組呢。
// 鍵值數組和value 保持對應關係
const keyArr = ['1,2,3,4,5','40']
const valArr = [f1,f2]
const getVal = (param = '')=>{
// 查找參數對應的下標
let index = keyArr.findIndex((it)=>{
return it.includes(param)
})
// 獲取對應值
return valArr[index]
}
let a = 2,
handle = getVal(a)
handle()
利用數組提供的下標,將key和value對應起來,進而獲取想要的值。
這裏一直沒有達到我最初的目的,即鍵裏面重複的數組,能夠不經過多餘操做匹配到,上面無論怎麼樣都進行了處理,這不是懶人的想要的。
若是想學習Java工程化、高性能及分佈式、深刻淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友能夠加個人Java高級交流:787707172,羣裏有阿里大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給你們。