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];
}
\