重构你的javascript代码
栏目: JavaScript · 发布时间: 5年前
内容简介:重构,对于每个开发者都至关重要,特别是对于那些需要进阶的高级程序员。根据二八理论,20%的重构方法,能解决80%的坏代码。笔者最近查阅较多js编码指南以及重新阅读了《代码整洁之道》、《重构:改善既有代码的设计》两本经典书籍(强烈建议每隔一段时间看,每次都有新体会),整理出以下几个要点,帮助大家以最小的记忆,重构大部分坏代码。如果想全面了解重构方式,可以看笔者整理的坏代码对每个人、每个项目标准都不一样,但以下几点大概率会是坏代码,需要使用重构方法进行代码重构。好的命名贯穿整个软件编码过程,好命名包括合理使用大
重构,对于每个开发者都至关重要,特别是对于那些需要进阶的高级程序员。根据二八理论,20%的重构方法,能解决80%的坏代码。笔者最近查阅较多js编码指南以及重新阅读了《代码整洁之道》、《重构:改善既有代码的设计》两本经典书籍(强烈建议每隔一段时间看,每次都有新体会),整理出以下几个要点,帮助大家以最小的记忆,重构大部分坏代码。如果想全面了解重构方式,可以看笔者整理的 AI Javascript风格指南
坏代码判断
坏代码对每个人、每个项目标准都不一样,但以下几点大概率会是坏代码,需要使用重构方法进行代码重构。
- 重复代码
- 过长函数
- 过大的类
- 过长参数列表
重构方法
1. 好的命名
好的命名贯穿整个软件编码过程,好命名包括合理使用大小写定义、缩进等。目前前端工程提供很多lint或format工具,能很方便的帮助工程检测和自动化,不清楚的同学可以看看笔者AI前端 工具 链。不管是变量名、函数名或是类名,一个好的命名会加快自身开发效率以及阅读代码效率,毕竟程序读的次数会比写的次数多的多。读github上优秀源码就知道,有时候只要看函数名就知道作者的意图。
// bad var yyyymmdstr = moment().format('YYYY/MM/DD'); // good var yearMonthDay = moment().format('YYYY/MM/DD'); 复制代码
// 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); 复制代码
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) } 复制代码
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 } 复制代码
// 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); 复制代码
// 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) } 复制代码
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() } 复制代码
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]() 复制代码
其他
实践以上列举的重构方法,能解决项目中大部分的坏代码,但还有许多重构方法,能让你的代码变得干净整洁易于阅读。
- 清晰的项目目录结构
-
ES6+语法糖
- arrow function
- rest
- 函数默认参数
- async/await
- let/const 代替var
- Array Methods
- 常用全部使用const,并字母全部为大写
- 使用合适的函数名或变量名代替注释
- 善于利用js中的&& 与 ||
- 避免‘否定情况’的判断
- 尽量不写全局函数与变量
- 采用函数式编程,ES6 Array支持的很好
- 移除重复的代码
- 移除注释的代码
参考文章
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Realm of Racket
Matthias Felleisen、Conrad Barski M.D.、David Van Horn、Eight Students Northeastern University of / No Starch Press / 2013-6-25 / USD 39.95
Racket is the noble descendant of Lisp, a programming language renowned for its elegance and power. But while Racket retains the functional goodness of Lisp that makes programming purists drool, it wa......一起来看看 《Realm of Racket》 这本书的介绍吧!