提高代碼幸福度,五個技巧減小js開發中的if else語句

 壹 ❀ 引數組

在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,那麼到這裏本文結束。

 參考

[淺析]特定場景下取代if-else和switch的方案

如何無痛下降 if else 麪條代碼複雜度

你本能夠少寫些 if-else

JavaScript 複雜判斷的更優雅寫法

相關文章
相關標籤/搜索