摘要: 好的注释能够提升代码的可读性和可维护性,从而提升代码质量。那么什么是好的注释?如何写出好的注释?api
“Comment or not comment, that is the question”函数
好的注释能够提升代码的可读性和可维护性,从而提升代码质量。工具
那么什么是好的注释?如何写出好的注释?本文将从注释的目的和原则出发对 JS 注释进行探讨。fetch
01ui
—this
注释的目的和原则spa
注释的目的:.net
注释的原则:prototype
咱们写注释,是为了给代码的读者(包括咱们本身,也可能包括机器,如 jsdoc)看,帮助读者阅读理解代码并进行维护。3d
「如无必要,勿增注释」是指注释要避免过多过滥,不要为了注释而注释。多余的注释等价于冗余的代码,除了对增长可读性无益,一旦代码须要修改,修改注释也会是一大负担。
咱们应当追求「代码自注释」,即代码自己就拥有较高的可读性(经过清晰的命名、合理的结构等)。举个例子:
// bad // 若是已经准备好数据,就渲染表格 if (data.success && data.result.length > 0) { renderTable(data); } // good const isTableDataReady = data.success && data.result.length > 0; if (isTableDataReady) { renderTable(data); }
「若有必要,尽可能详尽」是指须要注释的地方应该尽可能详尽地去写,以让阅读者能够充分了解代码的逻辑和意图为标准。
02
—
什么是好注释,什么是坏注释
根据注释的原则,咱们应该以「可否帮助阅读者更好地阅读理解代码」为标准,判断一个注释「是否有必要」。
好的注释包括:
init: function() {
// 获取配置信息
const config = getConfig();
// 获取用户信息
const userInfo = getUserInfo();
// 根据配置和用户信息,进行初始化
doInit(config, userInfo);
// 若是存在自定义配置时的特殊逻辑
if (config.custom) {
...
}
}
/**
* parseInt was the reason my code was slow.
* Bitshifting the String to coerce it to a
* Number made it a lot faster.
*/
const val = inputValue >> 0;
坏的注释包括:
// bad 单行注释过长,不易阅读,应写成多行
// parseInt was the reason my code was slow.Bitshifting the String to coerce it to Number made it a lot faster.
const val = inputValue >> 0;
// good
/**
* parseInt was the reason my code was slow.
* Bitshifting the String to coerce it to a
* Number made it a lot faster.
*/
const val = inputValue >> 0;
03
—
如何写好注释
注释规约
理解注释的目的和原则,制定并遵循一份注释规约,以保证注释的可读性和一致性
工具保障
好比使用 ESLint 保证注释风格的一致,使用 Sonar 检查项目注释率
04
—
注释规约
这里给出一份可供参考的注释规约(参考自airbnb规约):
4.1 【推荐】单行注释使用 //
注释应单独一行写在被注释对象的上方,不要追加在某条语句的后面:
// bad
const active = true; // is current tab
// good
// is current tab
const active = true;
注释行的上方须要有一个空行(除非注释行上方是一个块的顶部),以增长可读性:
// bad
function getType() {
console.log('fetching type...');
// set the default type to 'no type' const type = this.type || 'no type';
return type; }
// good
function getType() {
console.log('fetching type...');
// set the default type to 'no type' const type = this.type || 'no type';
return type; }
// good
// 注释行上面是一个块的顶部时不须要空行
function getType() {
// set the default type to 'no type' const type = this.type || 'no type'; return type; }
4.2 【推荐】多行注释使用 /** ... */,而不是多行的 //
// bad // make() returns a new element // based on the passed in tag name function make(tag) { // ... return element; } // good /** * make() returns a new element * based on the passed-in tag name */ function make(tag) { // ... return element; }
4.3 【强制】注释内容和注释符之间须要有一个空格,以增长可读性。eslint: spaced-comment
// bad
//is current tab
const active = true;
// good
// is current tab
const active = true;
// bad
/** *make() returns a new element *based on the passed-in tag name */
function make(tag) {
// ... return element; }
// good
/** * make() returns a new element * based on the passed-in tag name */
function make(tag) {
// ... return element; }
4.4 【推荐】使用特殊注释标记
有时咱们发现某个可能的 bug,但由于一些缘由还无法修复;或者某个地方还有一些待完成的功能,这时咱们须要使用相应的特殊标记注释来告知将来的本身或合做者。经常使用的特殊标记有两种:
class Calculator extends Abacus { constructor() { super(); // FIXME: shouldn’t use a global here total = 0; // TODO: total should be configurable by an options param this.total = 0; } }
4.5 【推荐】文档类注释,如函数、类、文件、事件等,使用 jsdoc 规范
例如:
/** * Book类,表明一个书本. * @constructor * @param {string} title - 书本的标题. * @param {string} author - 书本的做者. */ function Book(title, author) { this.title=title; this.author=author; } Book.prototype={ /** * 获取书本的标题 * @returns {string|*} */ getTitle:function(){ return this.title; }, /** * 设置书本的页数 * @param pageNum {number} 页数 */ setPageNum:function(pageNum){ this.pageNum=pageNum; } };
05
—
工具
咱们可使用一些工具来保证注释质量,例如:
Eslint:保证一致的注释风格
ESLint 是当下最流行的 JS 代码检查工具,ESLint 中有一些注释相关的规则,用户可选择开启:
Sonar:检查项目的注释率
Sonar 是一个代码持续集成平台,它能够对代码进行静态扫描,获得项目的注释率数据。
注释率反应了注释行占总代码行的比例,注释率过低很差,但也不能盲目追求高注释率。
另外,同 Eslint 相似,Sonar 也有一些针对注释风格规则能够配置。
06
—
后记
理解注释的目的和原则,遵循一份注释规约并结合工具保证落地,可使注释成为代码良好的辅助,加强可读性和可维护性,从而提升代码质量。
阅读更多干货好文,请关注扫描如下二维码: