Javascript命名规范与注释规范

601 阅读6分钟

1. 命名规范

驼峰式命名法介绍:

驼峰式命名法由小(大)写字母开始,后续每个单词首字母都大写。

按照第一个字母是否大写,分为:

Pascal Case 大驼峰式命名法:首字母大写。eg:StudentInfo、UserInfo、ProductInfo

Camel Case 小驼峰式命名法:首字母小写。eg:studentInfo、userInfo、productInfo


1.1 变量

命名方法:小驼峰命名法

命名规范:前缀应该是名词(函数的名字前缀为动词,以此区分变量和函数)

命名建议: 尽量在变量名中体现所属类型,如:length、count等表示数字类型;而包含name、title表示为字符串类型

示例

//好的命名方式
let maxCount = 10;
let tableTitle = 'LoginTable'; 
​
//不好的命名方法
let setCount = 10;
let getTitle = 10;

1.2 函数

命名方法:小驼峰命名法

命名规范:前缀应该是动词(变量的名字前缀为名词,以此区分变量和函数)

命名建议: 可使用常见的动词约定

动词含义返回值
can判断是否可执行某个动作(权限)函数返回一个布尔值。true:可执行;false:不可执行
has判断是否含有某个值函数返回一个布尔值。true:含有此值;false:不含有此值
is判断是否为某个值函数返回一个布尔值。true:为某个值;false:不为某个值
get获取某个值函数返回一个非布尔值
set设置某个值无返回值、返回是否设置成功或者返回链式对象
load加载某些数据无返回值或者返回是否加载完成的结果

示例:

//是否可读
function canRead() {
    return true;
}
​
//获取名称
function getName() {
    return this.name;
}

1.3 常量

命名方法: 名称全部大写

命名规范: 使用大写字母和下划线来组合命名,下划线用以分割单词。

命名建议: 无。

示例:

const MAX_COUNT = 10;
const URL = 'https://aurislee.com';

1.4 构造函数

介绍: 在js中,构造函数也属于函数的一种,只不过采用new运算符创建对象

命名方法: 大驼峰命名法,首字母大写

命名规范: 前缀为名称。

命名建议: 无。

示例:

function Student(name) {
    this.name = name;
}
​
let student = new Student('tom');

1.5 类的成员

类的成员包含:

  • 公共属性和方法:跟变量和函数的命名一样
  • 私有属性和方法:前缀为_(下划线),后面跟公共属性和方法一样的命名方式

示例:

function Student(name) {
    let _name name; //私有成员
    
    //公共方法
    this.getName = funciton () {
        return _name;
    }
    
    //公共方式
    this.setName = function () {
        _name = value;
    }
}
let student = new Student('tom');
student.setName('auris');
console.log(student.getName()); // => jerry: 输出_name私有变量的值

2. 注释规范

js支持两种不同类型的注释:单行注释和多行注释

2.1 单行注释

说明: 单行注释以两个斜线开始,以行尾结束。

语法: // 这是单行注释

使用方式:

  • 单独一行://(双斜线)与注释文字之间保留一个空格。
  • 在代码后面添加注释://(双斜线)与代码之间保留一个空格,并且//(双斜线)与注释文字之间保留一个空格。
  • 注释代码://(双斜线)与代码之间保留一个空格。

示例:

// 调用了一个函数;1)单独在一行
setTitle();
​
let maxCount = 10; // 设置最大量;2)在代码后面注释
​
// setName(); // 3)注释代码

2.2 多行注释

说明: 以/*开头,以/结尾

语法: /** 注释说明 */

使用方法:

/**
 * 代码执行到这里后会调用setTitle()函数
 * setTitle():设置title的值
 */
setTitle();

2.3 函数(方法)注释

说明: 函数(方法)注释也是多行注释的一种,但是包含了特殊的注释要求。

语法:

/** 
 * 函数说明 
 * @关键字 
 */

常用注释关键字:

注释名语法含义示例
@param@param 参数名 {参数类型} 描述信息描述参数的信息@param name {String} 传入名称
@return@return {返回类型} 描述信息描述返回值的信息@return {Boolean} true:可执行;false:不可执行
@author@author 作者信息 [附属信息:如邮箱、日期]描述此函数作者的信息@author 张三 2015/07/21
@version@version XX.XX.XX描述此函数的版本号@version 1.0.3
@example@example 示例代码演示函数的使用@example setTitle('测试')

示例:

/**
 * 合并Grid的行
 * @param {Grid} grid 需要合并的Grid
 * @param {Array} cols 需要合并列的Index(序号)数组;从0开始计数,序号也包含。
 * @param {Boolean} isAllSome 是否2个tr的cols必须完成一样才能进行合并。true:完成一样;false(默认):不完全一样
 * @return void
 * @author polk6 2015/07/21 
 * @example
 * _________________                             _________________
 * |  年龄 |  姓名 |                             |  年龄 |  姓名 |
 * -----------------      mergeCells(grid,[0])   -----------------
 * |  18  |  张三 |              =>             |      |  张三 |
 * -----------------                             -  18   ---------
 * |  18  |  王五 |                             |      |  王五 |
  -----------------                             -----------------
 */
function mergeCells(grid, cols, isAllSome) {
    // Do Something
}

更多注释内容,可参考JSDOC :usejsdoc.org

代码注释细节:

2.3.1 注释的说明

语法:写在注释块第一行

/**
 * events-function(这是注释的说明)
 * @description 切换音频播放状态(播放/停止)
 */
togglePlay: function() {
    // 省略其它代码...
}

2.3.2 标签

语法:@tagName

/** @function */
function fn() {
    return aurislee.com;
}

2.3.3 标签的说明

语法:- 说明文字

/**
 * @constructor Student - 学生
 * @param {string} name - 学生的名字
 */
 function Student(name) {
     
 }

2.3.4 参数类型

语法:{typeName} (可与标签结合使用,如@param)

/**
 * @param {string} a 必传参数
 */
function fn(a, b, c) {
​
}

2.3.5 可选参数类型

语法:[paramName] (可与标签结合使用,如@param)

/**
 *  @param {string} a 必传参数
 *  @param {number} [b] 可选参数
 */
function fn(a, b) {
​
}

2.3.6 参数有默认值

语法:[paramName=value] (可与标签结合使用,如@param)

/**
 *  @param {string} a 必传参数
 *  @param {number} [c=666] 参数有默认值
 */
function fn(a, c) {
​
}

2.3.7 链接

语法:[link text]{@link namepath Or URL}

/**
 * See {@link MyClass} and [MyClass's foo property]{@link MyClass#foo}.
 * Also, check out {@link http://www.google.com|Google} and
 * {@link https://github.com GitHub}.
 */

2.3.8 函数

/**
 * 转换时间字符串为时间对象
 * @function _str2time
 * @param strTime {String} - e.g "2017-02-13 10:02:58" or "2017-02-13" or "9:10"
 * @param type {String} - e.g date, dateTime, time
 */
function _str2time(strTime, type) {
    // 省略其它代码
}

2.3.8 类/构造函数

/**
 * 定时器
 * @class Timer
 */
​
function Timer() {
    this._timeId = 0;
    this._eventId = -1;
​
    this.eventHandler = {
        'stop': {}
    };
​
    /**
     * 定时器是否处于停止状态
     * @memberof Timer
     * @member stopped
     * @instance
     */
    this.stopped = true;
​
    /**
     * 启动定时器
     * @memberof Timer
     * @instance
     * @method start
     * @param {function} handler - 定时器每次执行时调用的函数
     * @param {number} interval - 定时器执行的时间间隔
     */
    this.start = function (handler, interval) {
        this.stopped = false;
        let _recursion = function() {
            this._timeId = setTimeout(() => {
                handler()
                    .then(() => {
                        if (this.stopped) {
                            clearTimeout(this._timeId);
                            this._trigger('stop');
                            return;
                        }
                        _recursion();
                    })
                    .catch(err => {
                        clearTimeout(this._timeId);
                        this.stopped = true;
                        this._trigger('stop');
                        if (err) throw new Error(err);
                    });
            }, interval)
        }.bind(this);
        _recursion();
    }
​
    /**
     * 停止定时器
     * @memberof Timer
     * @instance
     * @method stop
     */
    this.stop = function () {
        this.stopped = true;
    }
}
​
/**
 * 监听事件
 * @memberof Timer
 * @instance
 * @method on
 * @param {string} type - 事件类型  e.g 'stop'
 * @param {function} fn - 事件处理函数
 * @return {number} eventId - 事件处理函数Id,用于取消监听
 */
Timer.prototype.on = function (type, fn) {
    let _eventId = fn.name || ++this._eventId;
    this.eventHandler[type][_eventId] = fn;
    return _eventId;
}
​
/**
 * 触发事件
 * @private
 */
Timer.prototype._trigger = function (type) {
    let handlerMap = this.eventHandler[type];
    for (let key in handlerMap) {
        handlerMap[key]();
    }
}
​
/**
 * 取消监听事件
 * @memberof Timer
 * @instance
 * @method off
 * @param {string} type - 事件类型  e.g 'stop'
 * @param {function} target - 事件处理函数Id或者函数名字
 */
Timer.prototype.off = function (type, target) {
    let _target = (typeof target === 'function') ? target.name : target;
    delete this.eventHandler[type][_target];
}

\