Wang's blog Wang's blog
首页
  • 前端文章

    • HTML教程
    • CSS
    • JavaScript
  • 前端框架

    • Vue
    • React
    • VuePress
    • Electron
  • 后端技术

    • Npm
    • Node
    • TypeScript
  • 编程规范

    • 规范
  • 我的笔记
  • Git
  • GitHub
  • VSCode
  • Mac工具
  • 数据库
  • Google
  • 服务器
  • Python爬虫
  • 前端教程
更多
收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Wang Mings

跟随大神,成为大神!
首页
  • 前端文章

    • HTML教程
    • CSS
    • JavaScript
  • 前端框架

    • Vue
    • React
    • VuePress
    • Electron
  • 后端技术

    • Npm
    • Node
    • TypeScript
  • 编程规范

    • 规范
  • 我的笔记
  • Git
  • GitHub
  • VSCode
  • Mac工具
  • 数据库
  • Google
  • 服务器
  • Python爬虫
  • 前端教程
更多
收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Python爬虫

  • 前端教程

    • 团队规范

    • Project

      • Axios用法与原理
      • css布局技巧
      • 深度学习平台术语
      • 谈谈前端天花板问题
      • 一个程序员的成长之路
      • Markdown-It 解析原理
      • minipack源码解析
      • PostCSS
      • Electron工程踩坑记录
      • H5 Video踩坑记录
      • Puppeteer翻页爬虫
      • 重构你的javascript代码
        • [#](#坏代码判断) 坏代码判断
        • [#](#重构方法) 重构方法
          • [#](#_1-好的命名) 1. 好的命名
          • [#](#_2-函数单一职责) 2. 函数单一职责
          • [#](#_3-通过引入解释性变量或函数-使得表达更清晰) 3. 通过引入解释性变量或函数,使得表达更清晰
          • [#](#_4-更少的嵌套-尽早-return) 4. 更少的嵌套,尽早 return
          • [#](#_5-以hashmap取代条件表达式) 5. 以HashMap取代条件表达式
        • [#](#其他) 其他
        • [#](#参考文章) 参考文章
      • RxJS入门实践
      • 官网脚手架思考与实践
      • Stylelint样式规范工具
      • TypeScript开发Vue应用
      • Typescript tsconfig.json全解析
      • Vue项目TypeScript指南
      • TypeScript在Vue2.x中的坑
      • Vue Dialog弹窗解决方案
      • Vue JSX插件依赖及语法实践
      • Webpack 模块打包原理
      • Webpack4 配置详解
      • Webpack4 devServer配置详解
      • Webpack3.x升级Webpack4指南
    • JS

    • NodeJS

    • Vue

    • React

    • 效率工具

    • 读书笔记

  • 教程
  • 前端教程
  • Project
wangmings
2022-07-19
目录

重构你的javascript代码

# # 重构你的javascript代码

重构,对于每个开发者都至关重要,特别是对于那些需要进阶的高级程序员。根据二八理论,20%的重构方法,能解决80%的坏代码。笔者最近查阅较多js编码指南以及重新阅读了《代码整洁之道》、《重构:改善既有代码的设计》两本经典书籍(强烈建议每隔一段时间看,每次都有新体会),整理出以下几个要点,帮助大家以最小的记忆,重构大部分坏代码。如果想全面了解重构方式,可以看笔者整理的AI Javascript风格指南 (opens new window) (opens new window)

# # 坏代码判断

坏代码对每个人、每个项目标准都不一样,但以下几点大概率会是坏代码,需要使用重构方法进行代码重构。

  • 重复代码
  • 过长函数
  • 过大的类
  • 过长参数列表

# # 重构方法

# # 1. 好的命名

好的命名贯穿整个软件编码过程,好命名包括合理使用大小写定义、缩进等。目前前端工程提供很多lint或format工具,能很方便的帮助工程检测和自动化,不清楚的同学可以看看笔者AI前端工具链 (opens new window) (opens new window)。不管是变量名、函数名或是类名,一个好的命名会加快自身开发效率以及阅读代码效率,毕竟程序读的次数会比写的次数多的多。读github上优秀源码就知道,有时候只要看函数名就知道作者的意图。

    // bad
    var yyyymmdstr = moment().format('YYYY/MM/DD');
    
    // good
    var yearMonthDay = moment().format('YYYY/MM/DD');
    
1
2
3
4
5
6
    // bad
    function dateAdd(date, month) {
      // ...
    }
    
    let date = new Date();
    dateAdd(date, 1) // 很难理解dateAdd(date, 1)是什么意思。笔者注:这里单拎出来举例很简单易懂,但希望在做工程时也时刻谨记这条
    
    // good
    function dateAddMonth(date, month) {
      // ...
    }
    
    let date = new Date();
    dateAddMonth(date, 1);
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# # 2. 函数单一职责

软件工程中最重要原则之一。刚毕业不久的开发人员容易出现这个问题,觉得业务逻辑很复杂,没办法再细分成单独函数,写出很长的业务函数。但根据笔者指导小伙伴经验,大多数是临时变量过多,导致看不穿业务逻辑的本质;其实重构过程中一步步分解职责,拆分成细小函数并用恰当的名称命名函数名,能很快理解业务的本质,说不定还能发现潜藏的bug。

    // bad
    function handle(arr) {
        //数组去重
        let _arr=[],_arrIds=[];
        for(let i=0;i<arr.length;i++){
            if(_arrIds.indexOf(arr[i].id)===-1){
                _arrIds.push(arr[i].id);
                _arr.push(arr[i]);
            }
        }
        //遍历替换
        _arr.map(item=>{
            for(let key in item){
                if(item[key]===''){
                    item[key]='--';
                }
            }
        });
        return _arr;
    }
    
    // good
    function handle(arr) {
        let filterArr = filterRepeatById(arr)
        return replaceEachItem(filterArr)
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# # 3. 通过引入解释性变量或函数,使得表达更清晰

    // bad
    if (platform.toUpperCase().indexOf('MAC') > -1 && browser.toUpperCase().indexOf('IE') > -1 && wasInitialized() && resize > 0) {
      // do something
    }
    
    // good
    let isMacOs = platform.toUpperCase().indexOf('MAC') > -1
    let isIEBrowser = browser.toUpperCase().indexOf('IE') > -1
    let isResize = resize > 0
    if (isMacOs && isIEBrowser && wasInitialized() && isResize) {
      // do something
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
    // bad
    const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
    saveCityState(ADDRESS.match(cityStateRegex)[1], ADDRESS.match(cityStateRegex)[2]);
    
    // good
    var cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
    var match = ADDRESS.match(cityStateRegex)
    let [, city, state] = match
    saveCityState(city, state);
    
1
2
3
4
5
6
7
8
9
10
    // bad
    if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
      charge = quantity * _winterRate + _winterServiceCharge
    } else {
      charge = quantity * _summerRate
    }
    
    // good
    if (notSummer(date)) {
      charge = winterCharge(quantity)
    } else {
      charge = summerCharge(quantity)
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# # 4. 更少的嵌套,尽早 return

    // bad
    let getPayAmount = () => {
      let result
      if (_isDead) result = deadAmount()
      else {
        if (_isSeparated) result = separatedAmount()
        else {
          if (_isRetired) result = retiredAmount()
          else result = normalPayAmount()
        }
      }
    
      return result
    }
    
    // good
    let payAmount = () => {
      if (_isDead) return deadAmount()
      if (_isSeparated) return separatedAmount()
      if (_isRetired) return retiredAmount()
      return normalPayAmount()
    }
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# # 5. 以HashMap取代条件表达式

    // bad
    let getSpeed = type => {
      switch (type) {
        case SPEED_TYPE.AIR:
        return getAirSpeed()
        case SPEED_TYPE.WATER:
        return getWaterSpeed()
        ...
      }
    }
    
    // good
    let speedMap = {
      [SPEED_TYPE.AIR]: getAirSpeed,
      [SPEED_TYPE.WATER]: getWaterSpeed
    }
    let getSpeed = type => speedMap[type] && speedMap[type]()
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# # 其他

实践以上列举的重构方法,能解决项目中大部分的坏代码,但还有许多重构方法,能让你的代码变得干净整洁易于阅读。

  • 清晰的项目目录结构
  • ES6+语法糖
    • destructuring
    • rest
    • Array Methods
    • arrow function
    • 函数默认参数
    • async/await
    • let/const 代替var
  • 常用全部使用const,并字母全部为大写
  • 使用合适的函数名或变量名代替注释
  • 善于利用js中的&& 与 ||
  • 避免‘否定情况’的判断
  • 尽量不写全局函数与变量
  • 采用函数式编程,ES6 Array支持的很好
  • 移除重复的代码
  • 移除注释的代码

# # 参考文章

  • clean-code-javascript (opens new window) (opens new window)
  • JavaScript 编码风格指南 (opens new window) (opens new window)
  • Google JavaScript Style Guide (opens new window) (opens new window)
  • The AirBnb JavaScript Style Guide (opens new window) (opens new window)
编辑 (opens new window)
Puppeteer翻页爬虫
RxJS入门实践

← Puppeteer翻页爬虫 RxJS入门实践→

最近更新
01
theme-vdoing-blog博客静态编译问题
09-16
02
搜索引擎
07-19
03
友情链接
07-19
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式