原文链接:https://javascript.info/comments,translate with ❤️ by zhangbao.
从《代码结构》一章我们知道,注释分单行注释(以 // 开头)和多行注释(用 / … / 表示)。
我们通常使用它们来描述代码的工作方式和原因。
从第一眼看,注释应该是显而易见的,但在编程新手中的通常犯错。
坏的注释
新手倾向于使用注释来解释“代码中发生了什么”。是这样的:
// This code will do this thing (...) and that thing (...)
// ...and who knows what else...
very;
complex;
code;
但是在良好的代码中,这种“解释性”注释的数量应该是最小的。说真的,如果没有它们,代码应该很容易理解。
关于这一点有一个很好的规则:“如果代码如此不清楚,它需要注释,那么也许它应该被重写”。
秘诀:分解函数
有时用一个函数替换代码是很有好处的,比如这里:
function showPrimes(n) {
nextPrime:
for (let i = 2; i < n; i++) {
// check if i is a prime number
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert(i);
}
}
更好的变体,有一个分解函数 isPrime:
function showPrimes(n) {
for (let i = 2; i < n; i++) {
if (!isPrime(i)) continue;
alert(i);
}
}
function isPrime(n) {
for (let i = 2; i < n; i++) {
if (n % i == 0) return false;
}
return true;
}
现在我们可以很容易地理解代码了。函数本身变成了注释。这样的代码称为自描述。
秘诀:创建函数
如果我们有一个像这样的长“代码表”:
// 这里我们添加 whiskey
for(let i = 0; i < 10; i++) {
let drop = getWhiskey();
smell(drop);
add(drop, glass);
}
// 这里我们添加 juice
for(let t = 0; t < 3; t++) {
let tomato = getTomato();
examine(tomato);
let juice = press(tomato);
add(juice, glass);
}
// ...
然后,将其重构为这样的函数可能是一个更好的变体:
addWhiskey(glass);
addJuice(glass);
function addWhiskey(container) {
for(let i = 0; i < 10; i++) {
let drop = getWhiskey();
//...
}
}
function addJuice(container) {
for(let t = 0; t < 3; t++) {
let tomato = getTomato();
//...
}
}
函数本身再一次告诉我们发生了什么。没有什么可注释的。拆分时代码结构也更好,很清楚每个功能的功能,需要的功能和返回的功能。
实际上,我们不能完全避免“解释性”数值。存在复杂的算法,为了优化,或者一些智能的“调整”。 但一般来说,我们应该尽量保持代码简单和自我描述。
好的注释
所以,解释性的评论通常是不好的。哪些评论是好的?
描述了体系结构
提供组件的高级概述,它们如何交互,在各种情况下控制流程是什么……简而言之 - 鸟瞰代码。 对于高级架构图,有一种特殊的图表语言 UML,绝对值得研究。
记录一个函数用法
有一个特殊的语法 JSDoc 来记录一个函数:用法,参数,返回值。
例如:
/**
* 返回 x 求 n 次幂后的结果.
*
* @param {number} x 求幂的底数.
* @param {number} n 次幂,是一个自然数.
* @return {number} x 求 n 次幂后的结果.
*/
function pow(x, n) {
...
}
这样的注释使我们能够理解这个函数的目的,并且在不查看代码的情况下正确地使用它。
顺便说一下,许多像 WebStorm 这样的编辑器也能理解它们,并使用它们来提供自动完成和一些自动的代码检查。
此外,还有一些工具,如 JSDoc 3,可以从评论中生成 html 文档。您可以在 http://usejsdoc.org/ 上阅读关于 JSDoc 的更多信息。
为什么这个任务是这样解决的?
写的内容很重要。 但是,对于理解正在发生的事情,未写的内容可能更为重要。 为什么这个任务完全解决了? 代码没有回答。
如果有很多方法可以解决这个问题,那么为什么呢? 特别是当它不是最明显的时候。
如果没有这些注释,以下情况是可能的:
您(或您的同事)打开了一段时间以前编写的代码,并发现它是“不是最佳的”。
你会想:“那时我是多么的愚蠢,我现在有多聪明”,然后用“更明显、更正确”的变体重写。
重写的冲动是好的。但在这个过程中,你会发现“更明显”的解决方案实际上是缺乏的。你甚至模糊地记得为什么,因为你很久以前就已经试过了。你恢复到正确的变体,但是时间被浪费了。
解释解决方案的注释是非常重要的。它们有助于以正确的方式继续发展。
代码的任何细微特征?它们在哪里被使用?
如果代码有任何微妙和反直觉的东西,那么它绝对值得注释。
总结
一个好的开发者的一个重要标志是注释:他们的存在,甚至他们的缺席。
良好的注释使我们能够很好地维护代码,在延迟后再回到它并更有效地使用它。
像这样注释:
整体架构,高级视图。
函数功能。
重要的解决方案,特别是在不明显的情况下。
避免这样的注释:
这说明了“代码是如何工作的”和“它是怎么做的”。
只有在不可能使代码如此简单和自描述的情况下,才把它们放在一起,这样就不需要这些代码了。
注释也用于像 JSDoc3 这样的自动记录工具:他们读取并生成 HTML 文档(或以另一种格式的文档)。
(完)