JavaScript代码规范
行的长度
每行长度不应该超过120个字符,如果一行多余120个字符,应该在一个运算符后换行,下一行增加2级缩进,即8个空格)
doSomething(argument1, argument2, argument3, argument4,
argument5);
运算符间距
二元运算符前后必须使用一个空格保持表达式的整洁,操作符包括赋值运算符和逻辑运算符
var name = 'xuqi'; //GOOD
var name='xuqi'; //BAD
括号间距
当使用括号时,紧接左括号之后和紧接右括号之前不应该有空格。
doSomething(arg);//GODD
doSomething( arg );//BAD
字符串
- 使用单引号并保持一行,禁止在字符串中使用
\
另一起行; -
断行后字符串与上一行对齐
//GOOD var str = 'I am a programer.I love JS and' + 'Node'; //BAD var str = 'I am a programer.I love JS and \ Node';
空行
- 方法之间添加空行分隔
- 单行或多行注释前添加空行
- 逻辑块之间添加空行增加可读性
null使用场景
- 用来初始化一个变量,该变量可能被赋值为一个对象
- 用来和一个已经初始化的变量比较
- 当函数的参数期望为对象时,被用作参数传入
- 当函数的返回值期望是对象时,被用作返回值传出
undefined
禁止使用name === undefined
判断一个变量是否定义。应该使用typeof(name) === 'undefined'
;
对象直接量
- 起始左括号应该与表达式保持一行
- 每个属性的键名前保持一个缩进,第一个属性应该在左括号后另一起行
- 每个属性的键名不包含引号,其后跟一个冒号(前无空格,后有空格),然后是值
- 如果属性值为函数,函数体应该在属性名之下另起一行,并且其前后均应保留一个空行
- 一组相关属性的前后插入空行以提高代码的可读性
-
结束的右括号独占一行
var person = { name: 'xuqi', age: 25, // groupAttr1_1: xx1, groupAttr1_2: xx2, // walk: function() { // } };
-
当对象字面量作为函数参数时,起始括号应该与函数名同行
doSomething({ //do something });
声明
变量
- 所有变量在使用前应该先定义
- 变量定义应该放在函数开头
- 使用一个var表达式定义变量,每行定义一个
- 除了首行,所有行都应该多一层缩进使变量声明对齐
- 初始化的变量放在未初始化的变量之前
- 所有的变量命名必须使用英文单词
-
浮点变量必须指明实部(即便以0.开头)和小数点后一位
var name = 'xuqi', age, sex, ...
另外,变量名需要给出注释,否则别人很难读懂接下来代码的意思。
变量术语约定
变量可以按照一定规则命名也表示某些特定功能,比如:
- is前缀可以表示boolean值
- num或者count表示计数
- 错误加上Exception或者Error后缀
- ...
函数
- 函数在使用前应该先定义
- 函数名和开始圆括号之间无空格(包括匿名函数的function关键字与圆括号之间)
- 开始圆括号和结束圆括号之间无空格
- 参数名之间应该在逗号之后保留一个空格
- 开始花括号应该同function关键字保持同一行,结束圆括号和开始花括号之间应该保留一个空格
-
函数体保持一级缩进
function doSomething(arg1, arg2) { doThing1(); doThing2(); } // var method = function() { doSomething(); };
另外,IIFE的标准格式也在这里指出:
(function(args) {
//
}(args)); //(args)位于外层括号内
其他声明函数需要注意的方面:
-
循环中切勿加入函数,很容易因为闭包的原因造成错误。
//BAD for(i = 0; i < 3; i++) { setTimeout(function() { console.log(i); }, 0); }
-
“代码块”中切勿加入函数声明,混淆作用域
//BAD if (conditions) { function() { //doSomethings } }
命名
变量:
- 采用小驼峰命名格式
- 变量命名为名词(区别函数)
- 变量中不使用_
常量:
- 所有字符大写,不同单词之间适用单个下划线隔开
函数:
- 采用小驼峰命名格式
- 函数命名为动词(区别变量)
- 函数名中不使用_
构造函数:
- 采用大驼峰命名格式
- 命名应该是名词
私有成员:
- 一个对象中不希望外部访问的以下划线开头(约定)
表达式
赋值
当给变量赋值时,如果右侧是含有比较语句等形式的表达式时,用圆括号包裹
var flag = (i < count);//GOOD
var flag = i < count;//BAD
等号运算符
使用===
和!==
,禁止使用==
和!=
三目运算符
三目运算符应该仅仅使用在条件赋值语句中,禁止作为if的替代品
var val = codition ? val1 : val2;//GOOD
condition ? dothing1() : dothing2();//BAD
语句
每一行只包含一条语句,所有简单语句都应该以分号结束
return语句
当返回语句返回一个值的时候不应该使用圆括号包裹,除非在某些情况下这么做可以让返回值更容易理解
return abc;//GOOD
return (abc);//BAD
return (size > 0 ? size : default);//GOOD
if语句
if (condition) {
doSomething();
} else if (condition1) {
doSomething2();
} else {
soOtherThing();
}
for语句
//GOOD
var i;
for (i = 0; i < len; i++) {
doSomething();
}
for (i in collection) {
if (collection.hasOwnProperty(i)) {
doSomething();
}
}
//BAD
for (var i = 0; i < len; i++) {
doSomething();
}
for (i in collection) {
doSomething();
}
while,do语句
while (condition) {
doSomething();
}
do {
doSomething();
} while (condition)
switch语句
- 每一个case保持一个缩进,除第一个之外包括default在内的每一个case都应该在之前保留一个空行
- 每一组语句都应该以break,return等结尾,或者用一行注释表示跳过(falling through)
-
无default的情况也要注释特别说明
switch (val) { case 1: //nothing case 2: doSomething(); break; default: doDefault(); }
try语句
try {
doSomething();
} catch (err) {
doSomething2();
} finally {
doSomething3();
}
其他规范
- 禁止使用String等原始包装类型创建对象
- 禁止使用eval和with
- 避免使用try...catch...
- 使用for...in...的时候要添加hasOwnProperty判断
- 不给setTimeout和setInterval传递字符串参数,那就等同于eval了
模块化规范
CommonJs/CMD规范:
- 一个单独的文件就是一个模块,每个模块都有单独的作用域
- 模块标识可以为文件路径或者spm的包名称。require默认读取js文件,因此读取路径时可以省略.js后缀
- 模块与外部通信的桥梁为module.exports对象,通过exports.api可以对外抛出api接口。当然如果有需要,也可以通过module.exports = ...指定模块返回的内容而不仅仅是一个对象
- 模块引用通过require('module')可以获取module暴露的所有的接口
模块代码规范说明:
-
模块开头require加载所有依赖模块和JQ插件。如果是spm的依赖包,只要模块名即可,如果不是,需要写引用模块的相对路径+模块名
var $ = require('jquery'), tools = require('yoho-tools'), //spm包 flip = require('../plugin/flip'); //普通文件 require('../plguin/login'); ..
-
定义需要抛出的接口
exports.init = function() { //doInit }; exports.show = function() { //doShow }; ...
模块中不应该出现全局环境使用的变量或函数,这样可以保证模块的独立性
模块抛出接口应该给予注释说明功能和使用方法
其他事项
JS文件说明
/**
* 文件功能描述
* 使用方法
* author
* date
*/
函数的说明也采取类似格式:
/**
* 函数功能描述
* @param ...
* @returns ...
*/
附标签说明
JQuery插件规范
- 文件命名为jquery.plugin-name.js
- 所有新方法附加到jquery.fn对象,所有新功能附加到jquery对象
- this用于引用jquery对象
- 插件的开头带一个
;
,防止代码合并出现问题 - 除特殊注明外,所有方法必须返回jquery对象以便于链式调用
- 使用this.each迭代匹配的元素
- 在插件代码中使用
JQuery
而不是$
,减少命名冲突对我们的影响