前端代码注释

3,569 阅读5分钟
代码为什么需要注释

“代码千万行,注释第一行;编程不规范,同事两行泪;”代码注释为啥很重要呢?以下是我的一些想法:

  • 提高代码可读性

《黑客与画家》里面有句话“程序写出来是给人看的,附带能在机器上运行”。既然是给人看的,我觉得有两个方面就比较重要。一、代码写的好,好的代码依赖于coder的代码功底。要写出好的代码,需要多修炼内功。二、注释写的好。就像我们上学的时候看文言文,字基本都认识,但是连在一起就是不知道什么意思。这个时候就依赖于注释了,注释能把文言文中难懂的词汇翻译成白话。代码注释也是一样的道理,用来解释代码的意义。

  • 快速的导出接口文档

如果需要和外部对接时,优秀的代码注释可以通过 jsdoc快速导出接口文档

  • 提高代码编写效率和代码准确性

9102了大部分IDE都能根据注释去分析,提供一写智能提示,提高代码编写效率,降低我们代码的出错率。

代码注释的原则

一个原则是“as short as possible,as long as necessary ”。代码注释是必须的,但是要避免注释过多过滥,不要为了注释而注释。我们应该提高修炼好内容,提高代码本身的可读性。以下是一些需要添加注释的地方:

  • 文件描述注释
  • 类描述注释
  • 组件暴露出来的公共方法,工具类的方法、业务实现的关键方法
  • 关键变量、关键常量、TODO、约定的特殊标识
  • 解释复杂业务的实现逻辑
文件注释

文件头部增加文件注释,用于描述文件的基本信息。便于阅读代码时,快速的理解该文件的功能。 主要包含以下字段:

  • @description 文件描述
  • @author 作者
  • @date 创建时间
  • @lastModifiedBy 最新的变更人
  • @lastModifiedTime 最新的更新时间
/**
 * @description 文件干啥用的
 * @author CaiCai
 * @date 2019-2-20 16:16:52
 * @lastModifiedBy CaiCai·
 * @lastModifiedTime  2019-2-25 20:07:43
 */
类的注释

使用ES的语法Class定义一个类,主要包含如下字段:

  • @description 一个参数描述类的说明。
  • @property 描述public的实例属性。有三个参数,第一个参数表示属性的数据类型,用 {} 包含。第二个参数表示属性名。第三个参数用来表示属性的说明。 属性名和属性说明用‘ - ’连字符来连接,连接符前后需要空格
  • @hideconstructor 无参数,表示该类隐藏了构造函数。即定义中无构造函数,使用默认构造函数。有构造函数时,则不能使用该标识
  • @param 描述创建实例时的“参数”。有三个参数,第一个参数表示“参数”的数据类型,用 {} 包含。第二个参数表示“参数”名。第三个参数表示“参数”的说明。 “参数”和“参数”说明用‘ - ’连字符来连接,连接符前后需要空格
  • @extends 描述类继承自那个父类
  • @static 标识类的静态方法
/**
 * @description 一个参数用来描述类的主要功能
 * @property {string} props - 类的属性
 * @param {string} arg - 创建实例时的参数
 * @extends Parent
 */
class Test extends Parent {
    /**
     * @description 这是个静态方法
     * @returns { void }
     * @static
     */
    static testStaticMethod() {
    }
    constructor(arg) {
        super()
        this.props = arg
    }
}

JSDOC生成的接口文档:

Test类,通过JSDOC生成的接口文档

方法注释
  • @description 一个参数用来描述方法说明。
  • @param 描述创建实例时的“参数”。有三个参数,第一个参数表示“参数”的数据类型,用 {} 包含。第二个参数表示“参数”名。第三个参数表示“参数”的说明。 “参数”和“参数”说明用‘ - ’连字符来连接,连接符前后需要空格。如果“参数”是个对象则用多个@param 来声明。 “参数”名用[]括起来是,该参数是可选参数,[]内可以用=设置默认参数。“参数”是个数组时,数据类型后添加[]。
  • @returns 标识方法的返回值 包含两个参数。 第一个参数是返回的数据类型,可返回多种数据类型,用|分割。第二个参数是返回值的说明。
  • @example 通过例子来解释方法怎么用。
/**
 * @description 保存用户信息
 * @param { object } user - 用户
 * @param { string } user.name - 用户名
 * @param { number } user.age - 年龄
 * @param { boolean } [user.isMarried = false] - 是否已婚
 * @param { object[] } [exGirlFriends] - 前女友
 * @param { string } exGirlFriends[].name 前女友名字
 * @param { number } exGirlFriends[].age 前女友年龄
 * @param { number } [id] - 用户ID
 * @returns { (number|string) } 用户ID
 * @example
 * updateUserInfo({name:'CaiCai',age:26,isMarried:true})
 * // => 1
 */
function updateUserInfo() {

}

updateUserInfo方法,通过JSDOC生成的接口文档

单行注释

标识关键的变量、关键常量、TODO、约定的特殊标识等。单行注释用“//”开头,单行注释符后留一个空格。

// 这是单行注释
多行注释

描述关键代码或解释复杂业务的实现逻辑,提高代码可读性。 多行注释用“/*”开始,用“*/”结束。 开头和结束的*对齐

/*
 这是多行注释
 这是第二行
 */

以上是我对注释的一些思考,不适合所有人。大家可以在评论区,一起讨论“好的注释”。

参考文档:
注释那些事儿 - 前端代码质量系列文章(一)
JSDOC 官方文档
js/javascript代码注释规范与示例
Javascript注释规范