JS 优雅之道(JS 代码优化小 Tip)

5,285 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

写在前面

又是一年的毕业季,工作之余也浅叹一下,依稀记得当初因为太年轻,没有好的编码习惯也不注重编码效率,在实习阶段频繁加班的苦逼日子,今天抽空总结一下几个编程优化小Tip,给即将踏入前端俱乐部年轻的小可爱们做个参考,前辈就当温习一下,也欢迎大家补充指正!

JS 代码优化Tip

连环 if 优化

在许多业务中,往往会涉及很多的分支,当分支太多的时候,我们很容易像 code_1 那样将 if-else-if 写成非常 ugly 的代码段,那么有什么优化手段呢,接下来我们来看看代码

code-1 未优化的代码

逻辑很简单,根据 code 返回对应的颜色

// code-1
// 未优化前代码
function getColor(code){
  if(code === '200'){
    return 'blue-blue'
  }else if(code === '201'){
    return 'green-green'
  }else if(code === '202'){
    return 'red-red'
  }else{
    return 'other-other'
  }
}
console.log(getColor('200'))

code-2 使用 switch 优化

可以看出使用 switch 优化后代码行数并没有减少,仅仅是优化了结构,代码看起来更加舒服,阅读也相对更简单一些,而这并不是我们最优的选择

// code-2
// 使用 switch 优化
function getColor2(code){
  switch(code){
    case '200':
      return 'blue-blue'
      break
    case '201':
      return 'green-green'
      break
    case '202':
      return 'red-red'
      break
    default:
      return 'other-other'
      break
  }
}
console.log(getColor2('200'))

code-3 使用映射优化

很明显,使用映射优化的代码,代码量降低了,同时也没有影响代码的可读性,对于更加复杂的分支,通过映射的写法将会有更加明显的优势,而且这样做还有一个好处,如果分支非常复杂时,可以将映射抽离,作为 json 文件引入到代码中,进一步优化代码,更加易于维护

// code-3
// 使用映射优化 
function getColor3(code){
  var colorMap = {
    '200': 'blue-blue',
    '201': 'green-green',
    '202': 'red-red',
  }
  return colorMap[code] || 'other-other'
}
console.log(getColor3('200'))

可选链操作符 ?.

顾名思义,可选即当读取的属性在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,如 code-1,当我们无法确定 req 的数据结构的时候,那么如果想获取 type,就需要通过链操作 req.data.params.type 获取,而 req、data、params 中任何一个获取失败都会引起报错,所以需要通过 && 符号逐个判断

if(req && req.data && req.data.params && req.data.params.type === '200'){}

使用 ?. 优化

可以看出,使用 ?. 后代码简洁性和蹭蹭蹭往上涨!!

if(req?.data?.params?.type === '200'){}

合并对象

合并对象可以说是业务中非常非常常见的逻辑了,主要存在两种优化的写法

未优化代码

通过逐一赋值的方式合并,这种方式非常 ugly,随着 key 值越多,代码 ugly 的程度会急剧增加

let info = {
  name: 'yimwu',
  tel: '134xxxxx320'
}
let otherInfo = {
  name: 'yimwu',
  age: '18',
  address: 'gd'
}
info.age = otherInfo.age
info.address = otherInfo.address
console.log(info)

通过扩展运算符优化

let info = {
  name: 'yimwu',
  tel: '134xxxxx320'
}
let otherInfo = {
  name: 'yimwu',
  age: '18',
  address: 'gd'
}
info = {...info, ...otherInfo}
console.log(info)

通过 ES6 方法 Object.assign() 优化

let info = {
  name: 'yimwu',
  tel: '134xxxxx320'
}
let otherInfo = {
  name: 'yimwu',
  age: '18',
  address: 'gd'
}
Object.assign(info, otherInfo)
console.log(info)

深拷贝

我们都知道对象存在引用,当我们想将一个对象的所有内容赋值给另外一个对象时,如果只是简单的用 “ = ”赋值,两个对象将共享一块内存,也就是说两个对象指向同一个内存块的引用,那么之后改变任何一个对象中的值,两个对象都会同步改变,这并不是我们想要的,因此,在对象赋值时我们需要进行深拷贝,对对象进行拷贝赋值,保证两个对象指向不同的内存块,这样才能保证对象的修改不会互相影响

未优化代码

深拷贝传统的写法需要对对象进行深度遍历,每个对象的 key 逐个赋值

function deepClone(obj) {
  if (typeof obj != 'object') return obj;
  var temp = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
          if (obj[key] && typeof obj[key] == 'object') {
              temp[key] = deepClone(obj[key])
          } else {
              temp[key] = obj[key];
          }
      }
  }
  return temp;
}
let info = {
  name: 'yimwu',
  tel: '134xxxxx320',
  address: {
    home: 'jy',
    company: 'gz'
  }
}

let infoCopy = deepClone(info)

通过 JSON 方法优化

通过 JSON.parse 和 JSON.stringify 巧妙地将对象转化成字符串再进行解析,js 将重新赋值到新的内存块中,达到深拷贝的效果

let info = {
  name: 'yimwu',
  tel: '134xxxxx320',
  address: {
    home: 'jy',
    company: 'gz'
  }
}

let infoCopy = JSON.parse(JSON.stringify(info))

往期好文推荐

面试官:说说从输入 URL 到页面显示到底经历了什么,体现一下你的知识广度

面试官:作为前端,服务器相关了解多少?

面试官:HTTPS 采用的是对称加密还是非对称加密?具体说说其加密过程

面试官:说说 Cookie 和 Token 的区别?

面试官:网络安全了解多少,简单说说?(一)

面试官:网络安全了解多少,简单说说?(二)

面试官:网络安全了解多少,简单说说?(三)

面试官:网络安全了解多少,简单说说?(四)

面试官:网络安全了解多少,简单说说?(五)

面试官:网络安全了解多少,简单说说?(六)

面试官:网络安全了解多少,简单说说?(七)

面试官:网络安全了解多少,简单说说?(八)

浅尝 | 从 0 到 1 Vue 组件库封装

面试官:这么简单的正则表达式都不会?

Webpack 打包类库踩坑

面试官:你就只会 npm run build 吗?(Webpack 配置 Vue+Ts)

面试官:连VuePress都没搭过还说开发过组件库?(VuePress 搭建)

面试官: 连 Vue 视图更新都不会写?(Vue视图更新原理【一】)

面试官: 能不能手写 Vue 响应式?(Vue2 响应式原理【完整版】)

面试官:能不能手写 Vue3 响应式(Vue3 原理解析之响应系统的实现)

JS 优雅之道(JS 代码优化小 Tip)

面试官:你真的会用 SVG 吗? (SVG 应用实战)

面试官:说一下这个Loading动画实现思路 (CSS3 实现 Loading 动画)

JS 扫盲题 ( 面试题梳理系列 (一))

面试官:你确定你说的防抖不是节流吗?( 面试题梳理系列 (二))

面试官:除了 HTTP,你还用过什么通信协议?(Websocket 在数字孪生中的应用)

面试官:你真的理解 Event Loop 吗?( JS 事件循环 )

面试官:v-for 中 key 为什么不能用 index,从原理层面聊聊?

面试官:vue-router 的 hash 与 history 哪个模式会刷新页面?

面试官:说说你平时用过的自适应方案(数字孪生可视化自适应方案)

面试官:说一下如何优化过渡动画(数字孪生可视化过渡动画)

写在最后

博主接下来将持续更新好文,欢迎关注博主哟!!
如果文章对您有帮助麻烦亲点赞、收藏 + 关注和博主一起成长哟!!❤️❤️❤️