当前位置: 首页 > news >正文

注释那些事儿:前端代码质量系列文章(一)

为什么80%的码农都做不了架构师?>>>   hot3.png

摘要: 好的注释可以提高代码的可读性和可维护性,从而提高代码质量。那么什么是好的注释?如何写出好的注释?

“Comment or not comment, that is the question

 

好的注释可以提高代码的可读性和可维护性,从而提高代码质量。

 

那么什么是好的注释?如何写出好的注释?本文将从注释的目的和原则出发对 JS 注释进行探讨。

01

注释的目的和原则

注释的目的:

  • 提高代码的可读性,从而提高代码的可维护性

注释的原则:

  • 如无必要,勿增注释 ( As short as possible )

  • 如有必要,尽量详尽 ( As long as necessary )

我们写注释,是为了给代码的读者(包括我们自己,也可能包括机器,如 jsdoc)看,帮助读者阅读理解代码并进行维护。
「如无必要,勿增注释」是指注释要避免过多过滥,不要为了注释而注释。多余的注释等价于冗余的代码,除了对增加可读性无益,一旦代码需要修改,修改注释也会是一大负担。

我们应当追求「代码自注释」,即代码本身就拥有较高的可读性(通过清晰的命名、合理的结构等)。举个例子:

 

// 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;
  • 特殊标记注释:如 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;

 

  • 情绪性注释:如抱怨、歧视、搞怪等(被发现你就跪了160314_y4Fx_3552485.png

 

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,但因为一些原因还没法修复;或者某个地方还有一些待完成的功能,这时我们需要使用相应的特殊标记注释来告知未来的自己或合作者。常用的特殊标记有两种:

  • // 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;
  }
};

 

05

工具

我们可以使用一些工具来保证注释质量,例如:

Eslint:保证一致的注释风格

ESLint 是当下最流行的 JS 代码检查工具,ESLint 中有一些注释相关的规则,用户可选择开启:

  • valid-jsdoc

  • require-jsdoc

  • no-warning-comments

  • capitalized-comments

  • line-comment-position

  • lines-around-comment

  • multiline-comment-style

  • no-inline-comments

  • spaced-comment

Sonar:检查项目的注释率

Sonar 是一个代码持续集成平台,它可以对代码进行静态扫描,得到项目的注释率数据。

注释率反应了注释行占总代码行的比例,注释率太低不好,但也不能盲目追求高注释率。

另外,同 Eslint 类似,Sonar 也有一些针对注释风格规则可以配置。

06

后记

理解注释的目的和原则,遵循一份注释规约并结合工具保证落地,可以使注释成为代码良好的辅助,增强可读性和可维护性,从而提高代码质量。

原文链接

转载于:https://my.oschina.net/yunqi/blog/1802300

相关文章:

  • 专访腾讯云沙开波:从无到有,打造全球领先调度系统
  • 巨杉数据库:金融级数据库未来方向
  • Python之md5.update才过的哪些坑
  • IIS7/7.5/8如何实现访问HTTP跳转到HTTPS访问
  • overflow问题--滚动设置?
  • Apache Curator操作zookeeper的API使用
  • AutoEx应用崩溃自动匹配Stack Overflow的解答
  • Hessian入门
  • node常用模块---path
  • JPA的配置文件
  • 简单了解JS中的几种遍历
  • Go语言中的反射机制reflect
  • 面试题:servlet jsp cook session 背1
  • linux下安装redis扩展
  • 总结:设计模式之Template Method模式
  • hexo+github搭建个人博客
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【5+】跨webview多页面 触发事件(二)
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • CSS 提示工具(Tooltip)
  • Git同步原始仓库到Fork仓库中
  • node和express搭建代理服务器(源码)
  • PHP 7 修改了什么呢 -- 2
  • python学习笔记 - ThreadLocal
  • 对象管理器(defineProperty)学习笔记
  • 分布式任务队列Celery
  • 批量截取pdf文件
  • 前端工程化(Gulp、Webpack)-webpack
  • 前言-如何学习区块链
  • 如何解决微信端直接跳WAP端
  •  一套莫尔斯电报听写、翻译系统
  • 用Python写一份独特的元宵节祝福
  • 由插件封装引出的一丢丢思考
  • 自动记录MySQL慢查询快照脚本
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #QT(串口助手-界面)
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (2)STL算法之元素计数
  • (3)选择元素——(17)练习(Exercises)
  • (k8s中)docker netty OOM问题记录
  • (LeetCode 49)Anagrams
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Google的Objective-C编码规范
  • (转)菜鸟学数据库(三)——存储过程
  • (转载)Linux网络编程入门
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .NET开发不可不知、不可不用的辅助类(一)