「Comment or not comment, that is the question 」
好的註釋能夠提升代碼的可讀性和可維護性,從而提升代碼質量。javascript
那麼什麼是好的註釋?如何寫出好的註釋?本文將從註釋的目的和原則出發對 JS 註釋進行探討。前端
註釋的目的:java
提升代碼的可讀性,從而提升代碼的可維護性git
註釋的原則:github
如無必要,勿增註釋 ( As short as possible )api
若有必要,儘可能詳盡 ( As long as necessary )bash
咱們應當追求「代碼自注釋」,即代碼自己就擁有較高的可讀性(經過清晰的命名、合理的結構等)。舉個例子:微信
// bad
// 若是已經準備好數據,就渲染表格
if (data.success && data.result.length > 0) {
renderTable(data);
}
// good
const isTableDataReady = data.success && data.result.length > 0;
if (isTableDataReady) {
renderTable(data);
}複製代碼
「若有必要,儘可能詳盡」是指須要註釋的地方應該儘可能詳盡地去寫,以讓閱讀者能夠充分了解代碼的邏輯和意圖爲標準。網絡
根據註釋的原則,咱們應該以「可否幫助閱讀者更好地閱讀理解代碼」爲標準,判斷一個註釋「是否有必要」。ide
好的註釋包括:
幫助讀者更好地瞭解代碼邏輯和結構,例如:
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;
複製代碼
特殊標記註釋:如 TODO、FIXME 等有特殊含義的標記
文件註釋:部分規約會約定在文件頭部書寫固定格式的註釋,如註明做者、協議等信息
文檔類註釋:部分規約會約定 API、類、函數等使用文檔類註釋(如 jsdoc 風格)
遵循統一的風格規範,如必定的空格、空行,以保證註釋自身的可讀性
壞的註釋包括:
註釋對閱讀代碼無益:如本文第一個示例,本能夠不用註釋,用清晰的命名、邏輯進行代碼自注釋
未遵循統一的風格規範:如單行註釋長度、空格、空行,例如:
// 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;複製代碼
情緒性註釋:如抱怨、歧視、搞怪等(被發現你就跪了)
理解註釋的目的和原則,制定並遵循一份註釋規約,以保證註釋的可讀性和一致性
好比使用 ESLint 保證註釋風格的一致,使用 Sonar 檢查項目註釋率
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,但由於一些緣由還無法修復;或者某個地方還有一些待完成的功能,這時咱們須要使用相應的特殊標記註釋來告知將來的本身或合做者。經常使用的特殊標記有兩種:
// FIXME: 說明問題是什麼
// TODO: 說明還要作什麼或者問題的解決方案
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;
}
};複製代碼
咱們可使用一些工具來保證註釋質量,例如:
valid-jsdoc
require-jsdoc
no-warning-comments
capitalized-comments
line-comment-position
lines-around-comment
multiline-comment-style
no-inline-comments
spaced-comment
Sonar 是一個代碼持續集成平臺,它能夠對代碼進行靜態掃描,獲得項目的註釋率數據。
註釋率反應了註釋行佔總代碼行的比例,註釋率過低很差,但也不能盲目追求高註釋率。
另外,同 Eslint 相似,Sonar 也有一些針對註釋風格規則能夠配置。
理解註釋的目的和原則,遵循一份註釋規約並結合工具保證落地,可使註釋成爲代碼良好的輔助,加強可讀性和可維護性,從而提升代碼質量。
本篇是《前端代碼質量系列文章》的第一篇,後續系列文章還將討論編碼規約、複雜度、重複率等主題,敬請期待:)
本文部份內容和代碼示例參考:
aralejs註釋規範 https://github.com/aralejs/aralejs.github.io/wiki/JavaScript-註釋規範
airbnb編碼規約 https://github.com/airbnb/javascript#comments
http://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/comments/
部分配圖來自網絡,若有侵刪,請做者聯繫
關注微信公衆號查看更多原創內容