说明:本文档为前端JS规范
为提高团队协作效率,便于前端后期优化维护,输出高质量的文档。
提高代码可预测性和可维护性的方法是使用命名约定,这就意味着采用一致的方法来对变量和函数进行命名。
变量名包括全局变量,局部变量,类变量,函数参数
首字母大写,驼峰式命名。
JS中没有类,但是可以用new调用构造函数:var man = new Person();
首字母小写,驼峰式命名。如:checkCount
可根据团队及项目需要增加
$:表示Jquery对象
例如:$Content,$Module,一种比较广泛的Jquery对象变量命名规范。
可以根据项目及团队需要,设计出针对项目需要的前缀规范,从而达到团队开发协作便利的目的。
普通函数:首字母小写,驼峰式命名。
例如:getVersion(),submitForm();涉及返回逻辑值的函数可以使用is,has,contains等表示逻辑的词语代替动词,例如:isObject(),hasClass(),containsElment()。
内部函数:使用_fn+动词+名词形式,内部函数必需在函数最后定义。
例如:
function getNumber (total) {
if (total < 100) {
total = 100;
}
return _add(total);
function _add (number) {
number++;
return number;
}
}
alert(getNumber(10)); //alert 101
对象方法与事件响应函数:对象方法命名使用 对象类名+动词+名词形式;
例如: addressGetEmail()
事件响应函数:触发事件对象名+事件名或者模块名
例如:divClick(),addressSubmitButtonClick()
函数方法常用的动词:
get 获取/set 设置
add 增加/remove 删除
create 创建/destory 移除
start 启动/stop 停止
open 打开/close 关闭
read 读取/write 写入
load 载入/save 保存
create 创建/destroy 销毁
begin 开始/end 结束,
backup 备份/restore 恢复
import 导入/export 导出
split 分割/merge 合并
inject 注入/extract 提取
attach 附着/detach 脱离
bind 绑定/separate 分离
view 查看/browse 浏览
edit 编辑/modify 修改
select 选取/mark 标记
copy 复制/paste 粘贴
undo 撤销/redo 重做
insert 插入/delete 移除
add 加入/append 添加
clean 清理/clear 清除
index 索引/sort 排序
find 查找/search 搜索
increase 增加/decrease 减少
play 播放/pause 暂停
launch 启动/run 运行
compile 编译/execute 执行
debug 调试/trace 跟踪
observe 观察/listen 监听
build 构建/publish 发布
input 输入/output 输出
encode 编码/decode 解码
encrypt 加密/decrypt 解密
compress 压缩/decompress 解压缩
pack 打包/unpack 解包
parse 解析/emit 生成
connect 连接/disconnect 断开
send 发送/receive 接收
download 下载/upload 上传
refresh 刷新/synchronize 同步
update 更新/revert 复原
lock 锁定/unlock 解锁
check out 签出/check in 签入
submit 提交/commit 交付
push 推/pull 拉
expand 展开/collapse 折叠
begin 起始/end 结束
start 开始/finish 完成
enter 进入/exit 退出
abort 放弃/quit 离开
obsolete 废弃/depreciate 废旧
collect 收集/aggregate 聚集
为代码编写注释是非常重要的。通常人们在深入思考一个问题时,会非常清楚这段代码的工作原理。但是当过一周后再次回到该代码时,可能会花上很长时间来回想起那段代码到底是干什么的。
文件注释位于文件的最前面,应包括文件的以下信息:
文件名(必须),描述内容(必须),开源地址(开源必须),当前版本,作者,创建修改日期。
/*!
* @file axios.js
* @desc 易用、简洁且高效的http库
* @source https://github.com/axios/axios
* @version v0.19.0
* @author mzabriskie
* @date 2019-10-18
*/
单行注释
// this is comment
// TODO 未处理IE6-8的兼容性
多行注释
/*
*/
/* start
end */
模块注释
/**
* 模块说明
* @module 模块名
*/
例如:
/**
* Core模块提供最基础、最核心的接口
* @module Core
*/
/**
* 类说明
* @class 类名
* @constructor
*/
@class必须搭配@constructor或@static使用,分别标记非静态类与静态类。
/**
* 节点集合类
* @class NodeList
* @constructor
* @param {ArrayLike<Element>} nodes 初始化节点
*/
/**
* 方法说明
* @method 方法名
* @for 所属类名
* @param {参数类型} 参数名 参数说明
* @return {返回值类型} 返回值说明
*/
例如:
没有指定@for时,表示此函数为全局或模块顶层函数。当函数为静态函数时,必须添加@static;当函数有参数时,必须使用@param;当函数有返回值时,必须使用@return。
/**
* 返回当前集合中指定位置的元素
* @method
* @for NodeList
* @param {Number} [i=0] 位置下标。如果为负数,则从集合的最后一个元素开始倒数
* @return {Element} 指定元素
*/
@param。声明函数参数,必须与@method搭配使用。
当参数出现以下情况时,使用对应的格式:
[参数名]
参数有默认值:
[参数名=默认值]
/**
* 属性说明
* @property {属性类型} 属性名
*/
使用空格有助于改善代码的可读性和一致性。在撰写英文文章时在逗号和区间范围后面使用空格。在javascript采用同样的逻辑,可在列表表达式(等价于逗号)和语句结束(等价于完成一次“思考”)后面添加空格。
空格的另外一个很好的用途是用来分隔所有的操作符和操作,这也就是意味着在 +, -, *, =, <, >, <=, >=, ===, !==, &&, ||, += 等之后使用空格:
例子:
// 大量空格,并且使用一致,是的代码可读性更好
// 允许在阅读的时候不用一口气读下去
var d = 0,
a = b + 1;
if (a && b && c) {
d = a % c;
a += d;
}
// 反模式
// 缺少空格或空格使用不一致,使得代码比较混乱
var d= 0;
a =b+1;
if (a&& b&& c) {
d=a %c;
a+= d;
}
简单举例:
/**
* 翻转一个字符串
* @param {String} 输入需要翻转的字符串
* @return {String} 翻转后的字符串
**/
var reverse = function (input) {
// ...
return output;
};
YUIDoc范例:
完整范例:本程序由一个文件(app.js)组成。
app.js:
/*!
* @file app.js
* @desc 我的javascript应用程序
* @version v0.1.0
* @date 2019-10-18
*/
// 使用命名空间来定义一个空对象
var MYAPP = {};
// 定义一个包含两个方法(sum()和multi())的math_stuff对象
/**
* @namespace MYAPP
* class math_stuff
*/
MYAPP.math_stuff = {
/**
* Sums two numbers
* @method sum
* param {Number} 是第一个数
* param {Number} 是第二个数
* return {Number} 两个输入的总和
*/
sum: function (a, b) {
return a + b;
},
/**
* Multiplies two numbers
* param {Number} 是第一个数
* param {Number} 是第二个数
* return {Number} 两个输入相乘后结果
*/
multi: function (a, b) {
return a * b;
}
};
@namespace:这里用于命名包含以上对象的全局引用的名称
@class:这里有些命名不当,他实际意思是指对象或者构造函数
@method:定义对象中的方法和方法名
@param:列举函数所使用的参数。其中将参数类型用大括号括起来,并在其后注释参数名及描述。
@return:类似于@param,这里用于描述返回值的,并且该方法没有名称。
@constructor:表明这个“类”实际上是一个构造函数
@property和@type描述了对象的属性。
// 正确的书写
if (true) {
alert(name);
}
console.log(name);
// 不推荐的书写
if (true)
alert(name);
console.log(name);
// 不推荐的书写
if (true)
alert(name);
console.log(name)
// 没有换行,小的代码段无法区分
if (wl && wl.length) {
for (i = 0, l = wl.length; i < l; ++i) {
p = wl[i];
type = Y.Lang.type(r[p]);
if (s.hasOwnProperty(p)) {
if (merge && type == 'object') {
Y.mix(r[p], s[p]);
} else if (ov || !(p in r)) {
r[p] = s[p];
}
}
}
}
// 有了换行,逻辑清楚多了
if (wl && wl.length) {
for (i = 0, l = wl.length; i < l; ++i) {
p = wl[i];
type = Y.Lang.type(r[p]);
if (s.hasOwnProperty(p)) {
// 处理merge逻辑
if (merge && type == 'object') {
Y.mix(r[p], s[p]);
} else if (ov || !(p in r)) {
r[p] = s[p];
}
}
}
}
换行可以是空行,也可以是注释。
// 类的实现
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
alert(this.name);
};
var me = new Person("Nicholas");
// 将this放到局部变量self
function Persion(name, sex) {
var self = this;
self.name = name;
self.sex = sex;
}
平时咱们写代码,基本都是小程序,真心用不上什么继承,而且继承并不是JS的擅长的语言特性,尽量少用。如果非要使用的话,注意一点:
function A(){
// ...
}
function B(){
// ...
}
B.prototype = new A();
B.prototype.constructor = B; //原则上,记得把这句话加上
继承从原则上来讲,别改变他的构造函数,否则这个继承就显得很别扭了~
// 缓存对象
var getComment = function() {
var dom = $("#common-container"), // 缓存dom
appendTo = $.appendTo, // 缓存全局变量
data = this.json.data; // 缓存作用域链较深的对象
}
// 当需要缓存this时必须使用self变量进行缓存
// 缓存this
function Row(name) {
var self = this;
self.name = name;
$(".row").click(function() {
self.getName();
});
}
self是一个保留字,不过用它也没关系。在这里,看个人爱好吧,可以用_this, that, me等这些词,都行,但是团队开发的时候统一下比较好。
建议: 使用new Function来代替eval的使用,最好就别用。
var isHotel = json.type == "hotel" ? true : false
这个是要引起注意的,比如:
a = b // 赋值
(function(){
//....
})() // 自执行函数
未加分号,结果被解析成
a = b(function(){//...})() //将b()()返回的结果赋值给a
var is_hotel;
var isHotel;
var ishotel;
if (isHotel)
console.log(true)
else
console.log(false)
var json = eval(jsonText);
function() {
var isHotel = 'true';
.......
var html = isHotel ? '<p>hotel</p>' : "";
}
function() {
var isHotel = 'true';
// ....... 此处省略500行
return false;
}
window.onload只能使用一次,使用多次会被最后的覆盖。
解决方案:
CSS放在页头引入,javascript放在页尾引入
在上线之前,要编译压缩代码
减少重排与重绘