应用这 7 条规则来清理你的代码⚡️
可读的代码就是可维护的代码
在这篇短文中,我将介绍一些可以用来改进代码的规则。所有代码示例均为 JavaScript 代码。
我发现可读性强的代码才是可维护的。
作为一名开发者,我的目标是编写高质量的代码。团队中的每个开发者,无论其技能水平如何,都必须能够通过阅读来理解代码。这有助于年轻的开发者更有信心地编写代码。
消除
不必要代码注释
当然,有些代码可能非常复杂。我知道这一点,而且我见过很多次。在这里,我会添加适当的文档和代码注释。
别误会我的意思。我不喜欢代码注释,也不喜欢 JavaScript 的 JSdoc。或者至少在我不需要它们的时候不喜欢。;)
我不需要任何注释就能理解这个函数接收 X 个数组并将它们合并成一个新数组。
function mergeArrays(...arrays) {
let mergedArray = []
arrays.forEach(array => {
mergedArray = [...mergedArray, ...array]
})
return mergedArray
}
为这段代码添加 JSdoc 并不能提高可读性。我希望我的团队成员知道展开运算符是什么。如果他们不知道,应该在代码审查期间询问。
还有,别忘了注释掉的代码块。只有一个解决办法:删除那段代码。Git 有个很棒的功能可以检出旧代码,那干嘛还要把它留在注释里呢?
请不要把你的代码库变成垃圾场。
注重命名
如果你看一下名称mergeArrays,就应该很清楚这个函数将 X 个数组组合成一个新数组。
我知道命名很难。功能越复杂,命名就越难……我使用了一个规则来简化命名。以下是我的方法。
想象一下,一个函数合并两个数字数组,并生成一个新的唯一数字列表。你会怎么命名它?像这样?
function mergeNumberListIntoUniqueList(listOne, listTwo) {
return [...new Set([...listOne, ...listTwo])]
}
这个名字其实还不错,因为它的功能和它说的一样。问题在于这个函数做了两件事。一个函数的功能越多,命名就越困难。把它抽取成两个独立的函数会让它更容易理解,同时也更易于复用。
function mergeLists(listOne, listTwo) {
return [...listOne, ...listTwo]
}
function createUniqueList(list) {
return [...new Set(list)]
}
当然,不调用新函数,创建漂亮的单行代码很容易。但有时,单行代码的可读性并不高。
If 语句
我找不到这个问题的名字……瞧!命名很难……
但我经常看到这种情况。
问题
if(value === 'duck' || value === 'dog' || value === 'cat') {
// ...
}
解决方案
const options = ['duck', 'dog', 'cat'];
if (options.includes(value)) {
// ...
}
通过这样做,您可以创建一段看起来像英文句子的可读代码。
如果选项包含价值那么...
提前退出
有十几种方法可以命名这个原则,但我选择了“提前退出”这个名字。
让我给你展示一段代码。我相信你以前见过类似的代码。
function handleEvent(event) {
if (event) {
const target = event.target;
if (target) {
// Your awesome piece of code that uses target
}
}
}
这里我们尝试检查对象是否event
为 false 且属性target
是否可用。现在的问题是我们已经使用了 2 个if
语句。
让我们看看如何在这里“提前退出”。
function handleEvent(event) {
if (!event || !event.target) {
return;
}
// Your awesome piece of code that uses target
}
通过在此处应用“提前退出”,您可以检查event
和event.target
是否为假。很明显,我们确定event.target
不是假的。同样明显的是,如果此语句为假,则不会执行其他代码。
解构赋值
在 JavaScript 中,我们可以解构对象和数组。
根据在developer.mozilla.org上找到的文档,the descructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
一些代码示例
// Destructuring an object
const numbers = {one: 1, two: 2};
const {one, two} = numbers;
console.log(one); // 1
console.log(two); // 2
// Destructuring an array
const numbers = [1, 2, 3, 4, 5];
const [one, two] = numbers;
console.log(one); // 1
console.log(two); // 2
解构的问题在于,它有时会为属性创建一个不好的名称。一个完美的例子是从 API 获取数据并接收具有 data 属性的响应对象。
const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name} = response.data
此代码示例表明您正在获取 ID 为 1 的组织器。该组织器对象有一个名称,然后您对其进行了解构。这并没有错。
这段代码运行正常。但是为什么名称仍然是?它会是整个作用域中name
唯一的属性吗?而且,这个名称又是来自哪个对象呢?name
通过重命名属性可以避免这些问题。
const url = "http://localhost:8080/api/v1/organizers/1"
const response = await axios.get(url)
const {name: organizerName} = response.data
这段代码变得更易读了。每个人都会知道该变量是组织者的名字。
童子军规则
听说过这句话吗:“让它比你发现它时更好”?
嗯,这正是童子军的准则。让代码比你发现时更好。你发现了代码异味?那就重构它!你发现了未使用的变量?那就删除它!
我喜欢把它比作打扫房间的情况。想象一下,你家里的每个人都把碗碟放在水槽上,把所有垃圾都放在走廊上,把所有要洗的衣服都放在浴室里。但每个星期天,你都要打扫整个房子,这需要超过4个小时。你愿意吗?
我肯定答案是否定的。所以,如果每个人都立即清理房子里的小角落,周日的工作量就会小一些。
代码库也一样。如果代码库中残留着所有细微的代码异味,却没有人删除未使用的变量,那么代码检查器就会崩溃,发出大约 77 条警告。虽然有很多清理工作要做,但如果每个人都承担起自己的责任,并遵守童子军规则,很多问题就能迎刃而解。
代码风格
最后但同样重要的一点是,确定团队的代码风格。
我不在乎你喜欢用单引号还是双引号、空格还是制表符、尾部有逗号还是没有逗号。选择一种风格并坚持下去。你可以使用 linter 和/或 Prettier 来做到这一点。
有很多工具可以用来修复这类问题。我最喜欢的是使用Husky 的预提交钩子 (pre-commit hook) 。Prettier的文档中也有一个关于预提交钩子的页面。
此预提交钩子始终在每次提交前运行已配置的命令。如果您正确配置,它将运行 Prettier 并将所有规则应用于所有文件。这确保团队始终拥有相同的代码风格,不会出现任何错误代码。
结论
我知道有些规则显而易见,有些则不然。但作为一名全职开发人员,我经常在不同的代码库上工作。这些规则的重要性只有在大型代码库中才会凸显出来。但这并不意味着你不应该在小型项目中应用它们。提升代码质量将有助于你在小型项目中提高效率,也有助于你的团队更好地阅读代码并批准你的拉取请求。正如我所说,可读性高的代码更易于维护,但它也有很多其他优势。
如果您想了解更多关于代码整洁之道的知识,不妨阅读 Robert Martin 的《代码整洁之道》。如果您喜欢我的内容,请务必在Twitter上关注我,我会在那里发布我发布的所有博客链接。我争取每周发布一篇关于不同主题的文章。部分内容将在Medium上发布。
文章来源:https://dev.to/joachimzeelmaekers/clean-up-your-code-by-applying-these-7-rules-35ee