测试代码质量的唯一方式:别人看你代码时说 f * k 的次数。
代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。
code
本文并不是代码风格指南,而是关于代码的可读性、复用性、扩展性探讨。
我们将从几个方面展开讨论:
1、变量
2、函数
3、对象和数据结构
4、类
5、SOLID
6、测试
7、异步
8、错误处理
9、代码风格
10、注释
1、变量
用有意义且常用的单词命名变量
保持统一
可能同一个项目对于获取用户信息,会有三个不一样的命名。应该保持统一,如果你不知道该如何取名,可以去 codelf (https://unbug.github.io/codelf/) 搜索,看别人是怎么取名的。
每个变量名都该命名
可以用 buddy.js 或者 ESLint 检测代码中未命名的常量。
可描述
通过一个变量生成了一个新变量,也需要为这个新变量命名,也就是说每个变量当你看到他第一眼你就知道他是干什么的。
直接了当
避免无意义的前缀
如果创建了一个对象 car,就没有必要把它的颜色命名为 carColor。
使用默认值
2、函数
参数越少越好
如果参数超过两个,使用 ES2015/ES6 的解构语法,不用考虑参数的顺序。
如果参数超过两个,使用 ES2015/ES6 的解构语法,不用考虑参数的顺序
只做一件事
这是一条在软件工程领域流传久远的规则。严格遵守这条规则会让你的代码可读性更好,也更容易重构。如果违反这个规则,那么代码会很难被测试或者重用。
顾名思义
看函数名就应该知道它是干啥的。
对象设置默认属性
不要传flag参数
通过 flag 的 true 或 false,来判断执行逻辑,违反了一个函数干一件事的原则。
避免副作用(一)
函数接收一个值返回一个新值,除此之外的行为我们都称之为副作用,比如修改全局变量、对文件进行 IO 操作等。
当函数确实需要副作用时,比如对文件进行 IO 操作时,请不要用多个函数/类进行文件操作,有且仅用一个函数/类来处理。也就是说副作用需要在唯一的地方处理。
副作用的三大天坑:随意修改可变数据类型、随意分享没有数据结构的状态、没有在统一地方处理副作用。
避免副作用(二)
在 JavaScript 中,基本类型通过赋值传递,对象和数组通过引用传递。以引用传递为例:
假如我们写一个购物车,通过 addItemToCart() 方法添加商品到购物车,修改 购物车数组。此时调用 purchase() 方法购买,由于引用传递,获取的 购物车数组 正好是最新的数据。
看起来没问题对不对?
如果当用户点击购买时,网络出现故障, purchase() 方法一直在重复调用,与此同时用户又添加了新的商品,这时网络又恢复了。那么 purchase() 方法获取到 购物车数组 就是错误的。
为了避免这种问题,我们需要在每次新增商品时,克隆 购物车数组 并返回新的数组。
不要写全局方法
在 JavaScript 中,永远不要污染全局,会在生产环境中产生难以预料的 bug。举个例子,比如你在 Array.prototype 上新增一个 diff 方法来判断两个数组的不同。而你同事也打算做类似的事情,不过他的 diff 方法是用来判断两个数组首位元素的不同。很明显你们方法会产生冲突,遇到这类问题我们可以用 ES2015/ES6 的语法来对 Array 进行扩展。
比起命名式我更喜欢函数式编程
函数式变编程可以让代码的逻辑更清晰更优雅,方便测试。
封装条件语句
尽量别用“非”条件句
避免使用条件语句
Q:不用条件语句写代码是不可能的。
A:绝大多数场景可以用多态替代。
Q:用多态可行,但为什么就不能用条件语句了呢?
A:为了让代码更简洁易读,如果你的函数中出现了条件判断,那么说明你的函数不止干了一件事情,违反了函数单一原则。
避免类型检查(一)
JavaScript 是无类型的,意味着你可以传任意类型参数,这种自由度很容易让人困扰,不自觉的就会去检查类型。仔细想想是你真的需要检查类型还是你的 API 设计有问题?
避免副类型检查(二)
如果你需要做静态类型检查,比如字符串、整数等,推荐使用 TypeScript,不然你的代码会变得又臭又长。
不要过度优化
现代浏览器已经在底层做了很多优化,过去的很多优化方案都是无效的,会浪费你的时间,想知道现代浏览器优化了哪些内容,请点这里。
删除废弃代码
很多时候有些代码已经没有用了,但担心以后会用,舍不得删。
如果你忘了这件事,这些代码就永远存在那里了。
放心删吧,你可以在代码库历史版本中找他它。
3、对象和数据结构
用 get、set 方法操作数据
这样做可以带来很多好处,比如在操作数据时打日志,方便跟踪错误;在 set 的时候很容易对数据进行校验...
使用私有变量
可以用闭包来创建私有变量
4、类
使用 class
在 ES2015/ES6 之前,没有类的语法,只能用构造函数的方式模拟类,可读性非常差。
链式调用
这种模式相当有用,可以在很多库中发现它的身影,比如 jQuery、Lodash 等。它让你的代码简洁优雅。实现起来也非常简单,在类的方法最后返回 this 可以了。
不要滥用继承
很多时候继承被滥用,导致可读性很差,要搞清楚两个类之间的关系,继承表达的一个属于关系,而不是包含关系,比如 Human->Animal vs. User->UserDetails
5、SOLID
SOLID 是几个单词首字母组合而来,分别表示 单一功能原则、开闭原则、里氏替换原则、接口隔离原则以及依赖反转原则。
单一功能原则
如果一个类干的事情太多太杂,会导致后期很难维护。我们应该厘清职责,各司其职减少相互之间依赖。
6、测试
随着项目变得越来越庞大,时间线拉长,有的老代码可能半年都没碰过,如果此时上线,你有信心这部分代码能正常工作吗?测试的覆盖率和你的信心是成正比的。
PS: 如果你发现你的代码很难被测试,那么你应该优化你的代码了。
单一化
7、异步
不再使用回调
不会有人愿意去看嵌套回调的代码,用 Promises 替代回调吧。
Async/await比起Promise更简洁
8、错误处理
不要忽略抛异常
不要忘了在Promise抛异常
9、代码风格
代码风格是主观的,争论哪种好哪种不好是在浪费生命。市面上有很多自动处理代码风格的工具,选一个喜欢就行了,我们来讨论几个非自动处理的部分。
常量大写
10、注释
只有业务逻辑需要注释
代码注释不是越多越好。
删除注释得到代码
git 存在的意义就是保存你的旧代码,所以注释的代码赶紧删掉吧。
不要记日记
记住你有 git!,git log 可以帮你干这事。
注释不需要高亮
注释高亮,并不能起到提示的作用,反而会干扰你阅读代码。
关注公众号【grain先森】,回复关键词 【18福利】,获取为你准备的年终福利,更多关键词玩法期待你的探索~
网友评论