壹 ❀ 引數組
在JavaScript開發中,條件判斷語句的使用頻率是極高的,而對於條件判斷簡單易讀的if else應該都是你們的首選。但是代碼寫的久了,咱們老是但願本身的代碼看着能更爲簡潔規範(逼格更高),那麼今天咱們就由淺到深介紹幾種實用小技巧,幫你們減小代碼中的if else。說在開頭,本文並未有消滅或歧視 if else的意思,if else的好用都知道,這裏只是在某些特定場景爲你們額外提供一種思路罷了,如何使用還請自行抉擇,那麼本文開始。數據結構
貳 ❀ 短路求值函數
在函數定義時,常有若函數調用未提供參數則使用默認值的情景,固然咱們可使用if else來解決這個問題:post
function fn(name) { if(!name){ name = '聽風是風'; }; console.log(name); }; fn();//聽風是風 fn('行星飛行');//行星飛行
有沒有更優雅的作法呢?固然,咱們可使用短路求值,像這樣:spa
function fn(name) { name = name || '聽風是風'; console.log(name); }; fn();//聽風是風 fn('行星飛行');//行星飛行
咱們簡單複習下 ||或 和 &&與 的概念,||表示二者任意一個爲真便爲真,&&表示二者都爲真纔是真,任意一個爲假就是假。3d
爲何這個特定能用在變量賦值呢?其實這是利用了 || 前者爲真後者不判斷,&&前者爲假後者不判斷的特色,來看個例子:code
function fn() { console.log(1); }; true || fn(); //不執行 false && fn(); //不執行 false || fn(); //1 true && fn() //1
因此上面的短路求值中,當name有值時後面的默認值就被忽略了不判斷,而name無值時便會判斷後者取到默認值。對象
短路求值除了用在變量賦值外,還能用於函數調用,好比在下方例子爲假時才調用某個方法:blog
let name = false; function fn() { console.log(1); }; //if if (!name) { fn();//1 }; //短路 !name && fn();//1
對於函數形參短路賦值其實有個缺點,假設個人參數就是0,false或者null,由於短路的特性會被認爲假,這樣咱們沒法拿到想要的值,更佳的作法是使用ES6的形參默認值,像這樣:遞歸
function fn(param) { param = param || 1; console.log(param); }; fn(0); //1 fn(null); //1 fn(false); //1 //使用形參默認值 function fn1(param = 1) { console.log(param); }; fn1(); //1 fn1(0); //0 fn1(null); //null fn1(false); //false
叄 ❀ 三元運算符
三元運算符我想你們都不會陌生,在開發中三元運算的使用場景其實很是多,好比我但願爲條件爲 true時變量爲1,反之爲0,經過三元運算符咱們能夠這樣作:
let blo = true; let num; if (blo) { num = 1; } else { num = 0; }; console.log(num);//1 //三元運算符 blo =false; blo ? num = 1 : num = 0; console.log(num);//0
好比咱們但願條件爲true時調用函數fn,爲false時什麼也不作,使用三元看起來也會更加舒服:
let blo = true; let fn = function () { console.log(1); }; //if if (blo) { fn(); //1 }; //三元 blo ? fn() : null;//1
在開發中函數經常須要 return 一份數據回去,有時候根據條件不一樣咱們可能要分別對應返回不一樣的數據,三元也能解決這個問題:
let fn = function () { let flo = true; if (flo) { return 1; } else { return 2; }; }; let f = fn(); //1 let fn1 = function () { let flo = true; //三元 return flo ? 1 : 2; }; let f1 = fn1();//1
三元結合return的操做很是適合咱們遞歸處理時作收尾工做,若是知足條件繼續遞歸,不知足跳出遞歸,好比咱們要求正整數N到0之間全部整數之和,能夠這麼寫:
let result = 0; function add(n){ result += n return n>=2 ? add(n-1) : result; }; let num = add(10);//55
怎麼樣?看着是否是特別簡潔舒服。須要注意的是,三元運算符的表達式只能是單語句,不然沒法使用,好比下方例子中因爲執行語句超過了2句,這就沒法使用三元運算符改寫了:
let i = 5; if (i > 0) { //執行語句超過2句 console.log(1); i = 0; };
肆 ❀ switch case
短路求值與三元運算符當然好用,但其實有一個遺憾,它們都只能解決非A即B的條件判斷,凡是條件判斷超過兩種就顯得十分無力了。那難道咱們只能使用 else if 嗎,其實可使用switch case。
例如A狀況咱們但願A狀況輸出a,B狀況輸出b,C狀況輸出c,其它狀況輸出d,用 else if 與switch case分別是這樣:
let name = 'B'; //if else if if (name === 'A') { console.log('a'); } else if (name === 'B') { console.log('b'); } else if (name === 'C') { console.log('c'); } else { console.log('d'); }; //switch case switch (name) { case 'A': console.log('a'); break; case 'B': console.log('b'); break; case 'C': console.log('c'); default: console.log('d'); };
那麼咱們但願A或B狀況輸出1,C狀況輸出2,其它狀況輸出3呢,switch case其實也能作到:
let name = 'B'; //if else if if (name === 'A' || name === 'B') { console.log(1); } else if (name === 'C') { console.log(2); } else { console.log(3); }; //switch case switch (name) { case 'A': case 'B': console.log(1); break; case 'C': console.log(2); default: console.log(3); };
固然我想大多數人仍是會以爲switch case寫起來賊麻煩,儘管它的可讀性確實比 else if 更高,不要緊,就算做爲了解也沒有壞處。
伍 ❀ 對象配置
條件超過三種,else if 寫起來不太優雅,switch case又以爲麻煩,有沒有更棒的作法呢?我在實際開發遇到過這樣一個情景,我須要根據用戶不一樣的操做類型對同一份數據進行不一樣加工,好比新增,修改,刪除等。那麼我用else if是這麼作的:
function del() { //刪除操做 }; function add() { //新增 }; function update() { //更新 }; function process(operateType) { if (operateType === 'del') { del() } else if (operateType === 'add') { add() } else if (operateType === 'update') { update() }; }; process('del');//刪除
一種很棒的作法就是經過對象配置,將你的操做類型做爲key,具體操做的函數做爲value,像這樣:
function del() { //刪除操做 }; function add() { //新增 }; function update() { //更新 }; let typeFn = { 'del': del, 'add': add, 'update': update }; function process(operateType) { typeFn[operateType](); }; process('del'); //刪除
怎麼樣,有沒有眼前一亮呢?咱們將需求升級,如今除了判斷操做type類型外,還得額外附加一個狀態類型,else if是這樣,這裏簡單描述下:
function process(operateType, status) { if (operateType === 'del' && status === 1) { del() } else if (operateType === 'add'&& status === 2) { add() } else if (operateType === 'update'&& status === 3) { update() }; };
不太優雅,經過對象配置作法,咱們其實只用將參數簡單配置就OK了,像這樣是否是更清爽呢:
let typeFn = { 'del_1': del, 'add_2': add, 'update_3': update }; function process(operateType,status) { typeFn[`${operateType}_${status}`](); }; process('del',1); //刪除
什麼,你對象配置的調用方式語義化不太明顯?那各位可曾對ES6的map數據結構有了解呢,若是你以爲這樣的調用不太實在,咱們再改改,將調用條件與函數配置成map數據,像這樣:
let typeFn = new Map([ ['del_1', function () {/*do something*/ }], ['add_2', function () {/*do something*/ }], ['update_3', function () {/*do something*/ }], ]); function process(operateType, status) { typeFn.get(`${operateType}_${status}`)(); }; process('del', 1); //刪除
咱們經過map數據的get方法去數據中找到方法執行,這下可讀性總強一點了吧,諸君能否滿意呢?
陸 ❀ 數組配置
在處理條件判斷時,咱們常會遇到條件與對應結果所有已知的狀況,好比咱們要根據用戶的經驗設置等級頭銜,[0,100)--萌新,[100,200)--騎士,[200,300)--英雄,[300-無限大]--傳說,那麼用else if怎麼寫已經沒有懸念了:
function youAreMyHero(experience) { if (experience < 100) { return '萌新'; } else if (experience < 200 && experience >= 100) { return '騎士'; } else if (experience < 300 && experience >= 200) { return '英雄'; } else if (experience >= 300) { return '傳說'; }; }; let level = youAreMyHero(351); //傳說
對於這種條件與結果已知的狀況,咱們其實能夠經過數組配置的形式將條件結果抽離出來,像這樣:
function youAreMyHero(param) { let experience = [300, 200, 100]; let level = ['傳說', '英雄', '騎士', '萌新']; for (let i = 0; i < experience.length; i++) { if (param >= experience[i]) { return level[i]; }; }; return level[level.length - 1]; }; let level = youAreMyHero(250); //英雄
這麼作的好處就是便於管理條件與執行結果,若是後面新增了等級判斷,咱們不用去修改業務邏輯中的 else if 語句長度,只用單純維護咱們抽離的數據便可。
柒 ❀ 總
那麼到這裏,咱們大體介紹了五種可取代if else的方式,咱們知道短路運算符除了短路求值,還能用於函數調用;三元運算符也不只僅是處理變量賦值,在return場景結合三元用起來竟然如此溫馨。
在文章後半段,咱們還了解了對象配置,利用map數據結構,以及數據實行來解決特殊場景。我並不推薦爲了追求高逼格而犧牲代碼可讀性,但我更但願在你之後的代碼中不只僅只有if else,那麼到這裏本文結束。
參考