JS条件判断小技巧(一)

经常code review,我发现JS newbie很容易写出一堆冗长的代码。今天就列几个比较常见的“解决之道”,看看如何减少JS里的条件判断。

提前返回,少用if...else

if...else是编程语言的精华。——鲁迅”
但是过多的嵌套,还是挺令人抓狂的。这里有一个很典型的条件嵌套:

function func(){
  var result;

  if( conditionA ) {
    if( condintionB ) {
        result = 'Success';
    } else {
        result = 'Error1';
    }
  } else {
    result = 'Error2'
  }

  return result;
}

这种嵌套的特点就是else里的代码块很小,但是由于不得不做的分支语句导致多层嵌套。动动脑筋,怎样精简一下呢?在if里做判断——条件反转,并通过卫语句提前return else分支。

function func(){
  if( !conditionA ) {
    return 'Error2'
  }

  if( !condintionB ) {
    return 'Error1'
  }

  return 'Success';
}

forEach优化

遍历的时候也经常产生大量的嵌套,如下代码所示,我们先对数组元素做一次合法性校验,通过后再做一次新的操作,最后把操作结果追加到新数组里。

const func = (arr) => {
    const res = []
    arr.forEach( (e) => {
        if( e !== 'Onion' ){
            res.push(`${e} Run!`)
        }
    })
    return res;
}

仔细观察这就是一个filter加map的过程。我们不妨试试函数式编程:

const func = (arr) => {
    return arr
            .filer( (e) => e !== 'Onion' )
            .map( (e) => `${e} Run!` );
}

多条件,用Array.includes

再举个例子,某个页面需要检验输入type是否合法。我收到过一个MR曾经是这么写的。

const init(type) {
    if( type === 'Seminar' || type === 'Interview' ) {
        console.log('valid');
    }
    ...
    console.error('invalide');
}

如果合法的类型只有两种,代码其实也没啥问题。只是一般的业务很容易有后续的延展。今后将合法类型增加到10种的话,上述代码里将是一大长串的if判断。这种代码可读性极差,我们不如转换一下思想,把非法类型储到数组里,用Array.includes来帮你完成冗长的判断。之后每增加一种新的类型,只需在数组后追加新字符串就行了。

const init(type) {
    const invalidArray = ['Seminar', 'Interview']
    if( invalidArray.includes(type) ) {
        console.log('valid');
    }
    ...
}

使用object索引

类似的情况也出现在三元表达式里:

const dateFormat = (dateTime) => {
    const format = this.$i18n.locale === 'en' ? 'mmm d, yyyy' : 'yyyy年m月d日';
    return DateFormat(dateTime, format);
}

我们现阶段多语言只有enzh,上述代码自然不是问题,但是也难保哪天会支持日语——ja。这时候再写成下面这类代码就很搞笑了:

const format = this.$i18n.locale === 'en' ? 
'mmm d, yyyy' : 
(this.$i18n.locale === 'zh' ? 
     'yyyy年m月d日' : 'yyyy/m/d');

比较合适的写法就是使用object键索引,这样当语言业务扩展后,只需要在localeFormats后追加新格式就行了。

const localeFormats = {
    en: 'mmm d, yyyy',
    zh: 'yyyy年m月d日',
    ja: 'yyyy/m/d',
}

const format = localeFormats[this.$i18n.locale];

尽量少用swith

长Switch也及其难看。

export function(type) {
    switch( type ) {
        case 'Onion':
            return func1();
        case 'Garlic':
            return func2();
        case 'Ginger':
            return func3();
        default:
            return () => {console.error('ERROR')};
    }
}

我记得OOP设计模式里提到过:尽量使用多态和继承代替Switch结构。JS里倒不必非得往这方面想,用Object或是Map索引来代替Switch也是极好滴!

const arr = [
    ['Onion', func1],
    ['Garlic', func2],
    ['Ginger', func3],
]
const def = () => {console.error('ERROR')}
const vegetable = new Map(arr);

export function(type) {
    return ( vegetable.get(type) || def ).call(null);
}

Optional Chaining

Optional Chaining(以下简称OC)是我极力推荐的一个语法糖。我写过一期《Javascript Optional Chaining》具体介绍它的用法,有兴趣的小伙伴可以看一看,这里稍微点一下。比如我们想获取地址里的街道信息,但是并不确定地址本身是否存在,因此只能在获取街道前,事先判断一下地址合法性,一般我们会这么写:

if( address ) {
  var street = address.street;
}

但假如再多一层呢,从basicInfo.address.street这样找下来呢?

if( basicInfo ) {
    var address = basicInfo.address;
    if( address ) {
       var street = address.street;
    }
}

上面的代码我已经觉得很丑陋了,再多个几层真是没法看了。不过不用担心,有了OC一切迎刃而解。(虽然OC还在ECMAScript stage2,但是大家可以用babel尝鲜;babel会自动把如下源码转义成上面的形式)

var street = basicInfo?.address?.street;

写在最后

自学过几种编程语言,我感觉这类小技巧在各类语言中大同小异;实现上也许有细微差别,但基本思想都是一样的——减少大括号的数量!!
我在面试的时候经常看到一些人写代码及其冗长,嵌套极多。我提醒后,得到的回复一般是:“我没做过这种面试”,“我熟悉的是另外一种语言”等等。回过头来再想想,这真的是好理由吗?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343