JavaScript条件嵌套代码的可读性优化

数据结构

功能是实现历史记录的数据添加,数据按年月日组织以下:数据结构

"timeData": {
  "2019": {  //年
    "11": {  //月
      "12": [   //日
        {
          "start": "21:14",
          "end": "21:25",
          "duration": "0:11"
        },
        {
          "start": "23:34",
          "end": "23:45",
          "duration": "0:11"
        }
      ],
      "13": [
        {
          "start": "23:34",
          "end": "23:45",
          "duration": "0:11"
        }
      ]
    }
  }
}
复制代码

if else实现

添加时须要考虑没有对应年月日的状况,初次经过if else嵌套实现以下:函数

原理是依次尝试按指定日、月、年去获取数据,有数据则说明该日期以存在,该日没有则查月,月没有则查年,年没有则添加该年月日,有年无月则添加该月日,有月无日则添加该日。post

let dbData = getData(start.slice(0, 10)) //取指定年月日数据
  if (dbData) {
    dbData.push(data)
    save()
  } else {
    dbData = getData(start.slice(0, 7)) //取指定年月数据
    log('dbData', dbData)
    if (dbData) {
      dbData[sD] = [data]
      save()
    } else {
      dbData = getData(start.slice(0, 4)) //取指定年数据
      log('dbData', dbData)
      if (dbData) {
        dbData[sM] = { [sD]: [data] }
        save()
      } else {
        dbData = getData(start.slice(0, 0)) //取数据对象
        log('dbData', dbData)
        if (dbData) {
          dbData[sY] = { [sM]: { [sD]: [data] } }
          save()
        } else {
          log('Error: addTime startdata error')
        }
      }
    }
  }
复制代码

能够看到if else嵌套方式可读性较差,各级类似很难一眼看懂逻辑。spa

switch实现

下面经过dbData的“或”赋值和gData函数,减小冗余代码并巧妙的定位数据状况(location),并结合switch语句根据数据状况进行处理:code

let location: number = 0  
  let [ymd, ym, y] = [10, 7, 4] //ymd表明年月日的字符数,如: 2019-04-20 为10
  let dbData = gData(ymd) || gData(ym) || gData(y) || gData(0) //依次按日,月,年查找数据, 有则赋值
  function gData(i: number) {
    location = i //用于定位数据提取的级别
    return getData(start.slice(0, i))
  }

  //根据数据的级别添加数据, 好比有年无月,则添加月日数据
  switch (location) {
    case ymd:
      dbData.push(data)
      save()
      break
    case ym:
      dbData[sD] = [data]
      save()
      break
    case y:
      dbData[sM] = { [sD]: [data] }
      save()
      break
    case 0:
      dbData[sY] = { [sM]: { [sD]: [data] } }
      save()
      break
    default:
      log('Error: addTime startdata error')
      break
  }
复制代码

对象字面量实现

过了一天看到switch语句可用对象字面量替代,能大大下降圈复杂度,便将已上代码简化以下:cdn

let location: number = 0
  let [ymd, ym, y] = [10, 7, 4] //ymd表明年月日的字符数,如: 2019-04-20 为10
  let dbData = gData(ymd) || gData(ym) || gData(y) || gData(0) //依次按日,月,年查找数据, 有则赋值
  function gData(i: number) {
    location = i //用于定位数据提取的级别
    return getData(start.slice(0, i)) //经过日期查找对应的年月日数据
  }

  //根据已有的日期的状况添加数据, 好比有年无月,则添加月日数据
  let situation = {
    [ymd]: () => dbData.push(data),
    [ym]: () => (dbData[sD] = [data]),
    [y]: () => (dbData[sM] = { [sD]: [data] }),
    0: () => (dbData[sY] = { [sM]: { [sD]: [data] } }),
  }
  situation[location]()
  save()
复制代码

原文发布自:有度博客对象

相关文章
相关标签/搜索