壹 ❀ 引数组
在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,那么到这里本文结束。
参考