假設看到了這樣的代碼:javascript
if (a && d || b && c && !d || (!a || !b) && c) {
console.log('pass')
} else {
console.log('fail')
}
複製代碼
你是否一口老血噴在屏幕上?java
固然,這段代碼是我參考一個沸點(@隔壁村的李二狗)僞造的,希望你和你的同事都別這麼寫。canvas
能寫出這種與或非,若是不是邏輯不清,那麼估計只有一種可能,需求變動不少次,多人修改後的結果。。微信
如今的問題是,面對如此代碼,這麼複雜的邏輯,可否優化?優化
答案是確定的!動畫
這種問題的探究來自於一門數學:布爾代數或邏輯代數。ui
說到布爾,咱們開發者對此太熟悉了。不就是 true 和 false 嘛。spa
布爾代數這門課,大學裏應該或多或少都講些吧。由於我是數學專業畢業的,看到這種問題必須記錄一下,也順便複習一下。code
爲了方便表達,JS中的與或非,我用布爾代數裏面的表示方法(感謝掘金支持latex公式):cdn
所以 a && d || b && c && !d || (!a || !b) && c 能夠表達爲:
轉化後優先級清晰多了。
如今的問題是,咱們如何化簡這個邏輯表達式。
還好有一些經常使用結論可供咱們使用:
前四個公式很好理解。好比,本身或上本身否,固然爲 true。
關鍵在於第5個公式沒那麼直觀,能夠經過畫圖簡單說明下(其餘公式均可以相似推導)。
首先看部分,如圖中綠色區域:
再看,如圖中綠色區域:
則兩者之和爲:
而部分正是圖中粉色區域:
由於粉色區域本來就在前兩者之和裏面,所以加多少次都是同樣的。
注意最後這個公式核心特色:和是以和出現的。
有了這幾個公式做爲鋪墊,咱們就能夠正式推導了(原沸點配圖中有):
根據第4條,替換最後一項:
注意到前兩項分別有和,符合第5條:
此時最後兩項,符合第2條:
最後兩項知足第3條:
至此化簡完了。真是不能夠思議,B沒了!
此時開篇的代碼簡化成了這樣:
if (a && d || c) {
console.log('pass')
} else {
console.log('fail')
}
複製代碼
真清爽。
感謝你看到這裏,但願有所幫助。
今年年底,本人立了個flag,2020年要研究透canvas動畫技術。
圖中二維碼是個人惟一微信號,若有掘友想加的,麻煩備註下來源哈,好比【掘金】。
本文完。