js代碼優化之條件語句

在js的編碼過程當中,條件判斷能夠說是很是經常使用。當判斷條件過多或者邏輯比較複雜時,清晰的代碼結構和編碼思路顯得尤其重要。
需求描述:頁面列表-操做列-點擊不一樣的操做按鈕-作不一樣的事
下面介紹筆者在編碼過程當中,對條件判斷語句代碼的優化es6

if/else判斷

if(params == 'EDIT' ){
 	//to do
 }else if(params == 'VIEW'){
 	//to do
 }else if(params == 'DEL'){
 	// to do
 }
複製代碼
  • 優勢:簡單、熟悉
  • 缺點:條件過多時,代碼臃腫,邏輯不夠清晰;

總結:if/else是咱們最熟悉且經常使用的結構,可是當判斷分支過多時,十幾個if/else影響你的心情的同時代碼性能也收到了影響,對於代碼後期的優化重構,也帶來很大困難,這裏就不贅述了,讀者可自行腦補...。數組

switch/case判斷

switch(params){
	case 'EDIT':
	//to do
	break
	case 'VIEW':
	//to do 
	break
	case 'DEL':
	//to do 
	break
	default 
	//to do 
	break
}
複製代碼
  • 優勢:相較於ifelse-性能高、邏輯清晰、結構簡單
  • 缺點:沒有明顯缺點

總結:switch結構在代碼性能上比if/else結構訪問效率高的同時,代碼總體邏輯結構也顯得更加清晰明瞭緩存

Object對象參數

function handleClick(params){
    let actions={
		'EDIT':function(){},
		'VIEW':function(){},
		'DEL':function(){},
		'default':function(){}
    }
    return (actions[params] ||actions[default])()
}
//將判斷條件做爲對象的屬性名,將處理邏輯做爲對象的屬性值
複製代碼
  • 優勢:相較switch 結構優雅
  • 缺點:對象結構只適用在字符串結構下-actions的屬性名只能是字符串

es6 Set 和 Map 數據結構

js的對象(Object-鍵值對)傳統意義上只能是字符串做爲鍵,在特殊的場景下帶來了很大限制;markdown

若是將一個DOM節點做爲鍵,直接就會被自動轉爲字符串[object HTMLDivElement],ES6提供的Map數據結構,就能夠處理這種問題數據結構

//example:
const a =new Map();
const o = {params:'hi siri'};

a.set(o,'hello');
a.get(o)// hello

// main
function handleClick(params){
    let actions = new Map([
        ['EDIT',function(){}],
        ['VIEW',function(){}],
        ['DEL',function(){}],
        ['default',function(){}]
    ])
    return (actions.get(params)||actions.get('default'))()
}
複製代碼

到此彷佛一塊兒都已經結束了,有讀者也許會發文,以上結構適用在一元判斷沒有問題,若是是二元判斷、多元判斷以上還可否適用尼?
答案是確定能用,只是在結構和思路上有所調整ide

多元判斷

處理思路:在actions中列出每一個多元判斷條件下,所執行的函數步驟,多個傳參拼接成字符串,從actions中獲取函數函數

需求描述:判斷身份,再身份判別的基礎上再執行不一樣類型的操做,這裏以Mao結構舉例,Object結構相似oop

/** * identity manager:管理員;guest:客戶 * status 1:下單;2:付款;3:取消訂單 */

    let actions = new Map([
        ['manager_1',function(){}],
        ['manager_2',function(){}],
        ['manaber_3',function(){}],
        ['guest_1',function(){}],
        ['guest_3',function(){}],
        ['guest_3',function(){}],
        ['default',function(){}]
    ])
const handleClick=(manager,status)=>{
    let action = actions.get[`${manager}_${status}`]||actions.get['default']
    action.call(this)
}
複製代碼

如上需求描述,若是是客戶身份,假如 一、二、3狀態執行的方法都一致,又該當如何?

處理思路:緩存具備共性的函數性能

/** * identity manager:管理員;guest:客戶 * status 1:下單;2:付款;3:取消訂單 */
    let fnA = function(){}
    let fnB = function(){}
    let actions = new Map([
        ['manager_1',function(){}],
        ['manager_2',function(){}],
        ['manaber_3',function(){}],
        ['guest_1',fnA],
        ['guest_2',fnA],
        ['guest_3',fnA],
        ['default',function(){}]
    ])
const handleClick=(manager,status)=>{
    let action = actions.get[`${manager}_${status}`]||actions.get['default']
    action.call(this)
}
複製代碼

如上需求描述,fnA函數重複調用了三次,邏輯優化又該當如何?

處理思路:正則判斷參數,動態獲取執行函數優化

/** * identity manager:管理員;guest:客戶 * status 1:下單;2:付款;3:取消訂單 */
const actions = ()=>{
  const fnA = ()=>{}
  const fnB = ()=>{}
  return new Map([
    [/^guest_[1-2]$/,fnA],
    [/^guest_3$/,fnB],
    //...
  ])
}

const handleClick = (identity,status)=>{
    //map類型數據轉數組循環
  let action = [...actions()].filter(([key,value])=>(key.test(`${identity}_${status}`)))
  action.forEach(([key,value])=>value.call(this))
}
// 過濾出符合正則條件的邏輯函數,循環執行
複製代碼

此處不作過多介紹Map數據結構及方法,感興趣的同窗請參考阮一峯老師ECMAScript 6入門

彩蛋:

細心的讀者可能會發現文中函數聲明和調用方式也略有不一樣

  • Object聲明方式,當即執行函數調用
  • 函數聲明方式,正常調用

文後總結:

本文提供了7種判斷邏輯結構

  • if/else經常使用判斷結構
  • switch/case判斷結構
  • Object對象參數結構
  • es6-map數據結構-
  • 多元判斷-經常使用結構
  • 多元判斷-函數緩存結構
  • 多元判斷-正則判斷、動態返回結構

需求變化千千萬,更多的編碼思路值得咱們去發掘,有興趣的同窗能夠來補充。 本文所述內容,若有疑問請隨時與筆者聯繫;如發現問題,歡迎隨時指正。

相關文章
相關標籤/搜索