讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議13:養成優化表達式的思維方式 >

建議13:養成優化表達式的思維方式

對同一個表達式稍加改動就會打亂表達式的邏輯運算順序,因此我們應該學會優化表達式的結構,不改變表達式的運算順序和結果即可提高代碼的可讀性。

1.第一種方式——加小括號

例如,面對下面這個複雜表達式,可能被&&和||的優先級所迷惑。


(a+b>c&&a-b<c||a>b>c)


不過,如果進行如下優化,邏輯運算的順序就會非常清晰了。


((a+b>c)&&((a-b<c)||(a>b>c)))


雖然增加這些小括號顯得多餘,但是這麼寫並沒有影響表達式的實際運算,反而帶來了非常明顯的好處。學會使用小括號分隔符來分隔表達式的邏輯層次,不失為一種高明之舉。

使用小括號分隔符來優化表達式內部的邏輯層次,是一種很好的設計習慣。如果複雜表達式中存在一些與人的思維方式相悖的不良的邏輯結構,也會影響人們對代碼的閱讀和思考,這個時候就應該根據人的思維習慣來優化表達式的邏輯結構。

2.第二種方式——改變表達式結構順序

例如,想設計一個表達式來篩選學齡人群,即年齡大於或等於6歲且小於18歲的人:


if(age>=6&&age<18){

}


直觀閱讀,表達式age>=6&&age<18可以很容易被每一個人所理解。繼續複雜化表達式:篩選所有弱勢年齡人群,以便在購票時實施半價優惠,即年齡大於或等於6歲且小於18歲,或者年齡大於或等於65歲的人:


if(age>=6&&age<18||age>=65){

}


從邏輯上分析,上面表達式沒有錯誤。但是從結構上分析就感覺比較模糊,為此我們可以使用小括號來分隔邏輯結構層次,以方便閱讀。


if((age>=6&&age<18)||age>=65){

}


但是,此時如果根據人的思維來思考條件表達式的邏輯順序時,會發現它有些紊亂,與人的一般思維方式發生了錯位。人的思維是一種線性的、有聯繫、有參照的一種方式,如圖1.1所示。

圖 1.1 人的思維模型圖

對於表達式(age>=6&&age<18)||age>=65來說,其思維模型圖如圖1.2所示。通過對此模型圖的直觀分析,會發現該表達式的邏輯是非線性的,呈現多線思維的交叉型,這種思維結構對於機器計算來說基本上沒有任何影響。但是對於人腦思維來說,就需要認真思考之後,才能把這個表達式中各個小的表達式邏輯單元串聯在一起,形成一個完整的邏輯線。

圖 1.2 表達式的思維模型圖

直觀分析,這個邏輯結構的錯亂是因為隨意混用大於號和小於號等運算符造成的。如果調整一下表達式的結構順序,閱讀起來就非常清晰了。


if((6<=age&&age<18)||65<=age){

}


這裡採用了統一的小於號方式,即所有參與比較的項都按著從左到右、從小到大的思維順序進行排列,而不再遵循變量始終居左、比較值始終居右的傳統編寫習慣。

3.第三種方式——避免布爾表達式的疊加

表達式中的另一個「頑疾」是布爾型表達式的重疊所產生的迷宮。在複雜表達式中,這種多重疊加的布爾表達式足以「令人生畏」。例如,對於下面這個條件表達式:


if!(!isA||!isB){

}


如果採用「剝洋蔥皮」的方法逐層分析,也可以找到結果。當然,也可以對這樣的表達式進行優化,以方便閱讀。例如:


(!isA||!isB)=!(isA&&isB)

(!isA&&!isB)=!(isA||isB)


?運算符為很多程序員所喜愛,特別是在JavaScript函數式編程中,這個運算符的使用頻率會更高。但對於很多開發者來說,由於難以適應這種連續思維,會在閱讀代碼時產生障礙。為此,可以適當採用if條件語句對?運算符表達式進行分解。

4.第四種方式——if語句分解

例如,對於下面這個複雜表達式,如果不仔細進行分析,很難理清它的邏輯順序。


var a.b=new c(a.d?a.e(1):a.f(1))


在使用if條件語句後,邏輯結構就變得非常清晰了。


if(a.d){

var a.b=new c(a.e(1));

}else{

var a.b=new c(a.f(0));

}