代码风格
文件
[强制] JavaScript 源码文件必须以 UTF-8 无 BOM 编码。
缩进
[强制] 使用 4 个空格缩进。不允许使用 tab 或 2 个空格。
[强制] switch 中的 case 和 default 必须缩进。
// good
switch (variable) {
case '1':
// do...
break;
case '2':
// do...
break;
default:
// do...
}
// bad
switch (variable) {
case '1':
// do...
break;
case '2':
// do...
break;
default:
// do...
}
空格
[强制] 二元运算符两侧必须用空格隔开。但一元运算符与其操作数之间不留空格。
let a = !arr.length;
a++;
a = b + c;
[强制] 在左花括号前留 1 个空格。
// good
if (condition) {
}
set('attr', {
some: 'xxx',
any: 'yyy'
});
function funcName() {
}
// bad
if (condition){
}
set('attr',{
some: 'xxx',
any: 'yyy'
});
function funcName(){
}
[强制] 在 if / else / for / while / function / switch / do / try / catch / finally 之后留 1 个空格。
// good
if (condition) {
}
while (condition) {
}
(function () {
})();
// bad
if(condition) {
}
while(condition) {
}
(function() {
})();
[强制] 在创建对象的语句中,: 之后留 1 个空格,之前不留空格。
// good
const obj = {
a: 1,
b: 2,
c: 3
};
// bad
const obj = {
a : 1,
b:2,
c :3
};
[强制] 在函数声明、具名函数表达式和函数调用中,函数名与 ( 之间不留空格。
// good
function funcName() {
}
const funcName = function funcName() {
};
funcName();
// bad
function funcName () {
}
const funcName = function funcName () {
};
funcName ();
[强制] , 和 ; 之前不留空格。
// good
callFunc(a, b);
// bad
callFunc(a , b) ;
[强制] ( 和 [ 之后,以及 ) 和 ] 之前不留空格。
// good
callFunc(param1, param2, param3);
save(this.list[this.indexes[i]]);
needIncream && (variable += increament);
if (num > list.length) {
}
while (len--) {
}
// bad
callFunc( param1, param2, param3 );
save( this.list[ this.indexes[ i ] ] );
needIncreament && ( variable += increament );
if ( num > list.length ) {
}
while ( len-- ) {
}
// good
const arr1 = [];
const arr2 = [1, 2, 3];
const obj1 = {};
const obj2 = {name: 'obj'};
const obj3 = {
name: 'obj',
age: 20,
sex: 1
};
// bad
const arr1 = [ ];
const arr2 = [ 1, 2, 3 ];
const obj1 = { };
const obj2 = { name: 'obj' };
const obj3 = {name: 'obj', age: 20, sex: 1};
[强制] 每行末尾不得有空格。
换行
[强制] 在语句结束处换行。
[强制] 每行不得超过 120 个字符。
[强制] 如果换行,运算符必须放在行首。
// good
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
|| user.hasAuthority('delete-admin')
) {
// Code
}
const result = number1 + number2 + number3
+ number4 + number5;
// bad
if (user.isAuthenticated() &&
user.isInRole('admin') &&
user.hasAuthority('add-admin') ||
user.hasAuthority('delete-admin')) {
// Code
}
const result = number1 + number2 + number3 +
number4 + number5;
[强制] 如果括号内的内容占据多行,则 )、]、} 需另起一行,并与对应的 (、[、{ 所在的行保持相同的缩进。
// good
if (product) {
product.load();
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
) {
sendProduct(user, product);
}
}
const arr = [
'candy', 'sugar'
];
// bad
if (product) {
product.load();
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')) {
sendProduct(user, product);
}
}
const arr = [
'candy', 'sugar'
];
[强制] 不得在 , 或 ; 前换行。
// good
const obj = {
a: 1,
b: 2,
c: 3
};
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
// bad
const obj = {
a: 1
, b: 2
, c: 3
};
foo(
aVeryVeryLongArgument
, anotherVeryLongArgument
, callback
);
[建议] 关于换行和缩进的建议
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
) {
// Code
}
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
baidu.format(
dateFormatTemplate,
year, month, date, hour, minute, second
);
$('#items')
.find('.selected')
.highlight()
.end();
const result = thisIsAVeryVeryLongCondition
? resultA : resultB;
const res = condition
? thisIsAVeryVeryLongResult
: resultB;
[强制] 如果使用多行代码块,else 和 catch 必须另起一行。
// good
if (condition) {
// some statements;
}
else {
// some statements;
}
try {
// some statements;
}
catch (ex) {
// some statements;
}
// bad
if (condition) {
// some statements;
} else {
// some statements;
}
try {
// some statements;
} catch (ex) {
// some statements;
}
语句
[强制] 语句末尾的分号不得省略。
[强制] 即使只有一行,{} 也不能省略。
// good
if (condition) {
callFunc();
}
// bad
if (condition) callFunc();
if (condition)
callFunc();
[强制] 函数定义结束处不加分号。
// good
function funcName() {
}
// bad
function funcName() {
};
// For function expression, the semicolon must not be ignored.
const funcName = function () {
};
[强制] 对象和数组声明中不得有尾随逗号。
// good
const obj = {
attr1: 'xxx',
attr2: 'yyy'
};
const arr = [
'xxx',
'yyy'
];
// bad
const obj = {
attr1: 'xxx',
attr2: 'yyy',
};
const arr = [
'xxx',
'yyy',
];
命名规范
[强制] 变量、属性和函数名使用小驼峰命名法 (lowerCamelCase)。
const loadingModules = {};
function loadProduct() {
}
[强制] 类名使用大驼峰命名法 (UpperCamelCase/Pascal)。
function Element(options) {
}
[建议] 缩写词的所有字母应当全部大写或全部小写。
function parseSVG() {
}
const svgParser;
语言特性
兼容性
语言特性可以通过一些工具库进行 polyfill,但绝不能通过修改原生 JS 对象的原型来实现。
// good
import * as zrUtil from 'zrender/src/core/util';
zrUtil.each(array, function (val, index) {
sum += val;
});
const result = zrUtil.map(array, function (val) {
return parse(val);
});
const pos = zrUtil.indexOf(array, val);
const obj2 = zrUtil.extend({}, obj1);
function Element() {
// ...
}
// bad
array.forEach(function (val, index) {
sum += val;
});
let result = array.map(function (val) {
return parse(val);
});
const pos = array.indexOf(val);
const obj2 = Object.assign({}, obj1);
class Element {
// ...
}
String.prototype.trim = function () {
};
变量
[强制] 优先使用 const 声明变量。一行不能声明多个变量。
// good
const name = 'MyName';
const hangModules = [];
const missModules = [];
const visited = {};
// bad
name = 'MyName';
const hangModules = [],
missModules = [],
visited = {};
条件
[强制] 在相等表达式中,== 仅可用于 null 或 undefined 的检测。其余情况应当使用 ===。
// good
if (age === 30) {
// ...
}
if (type == null) {
// ...
}
// bad
if (age == 30) {
// ......
}
[建议] 使用 xxx == null 来判断 null 或 undefined。
[建议] 尽量让 null 和 undefined 的含义保持一致,即:不要让用户或开发者去区分一个变量是 null 还是 undefined。
[建议] 函数表达式或函数声明不应置于循环体内。
// good
function clicker() {
// ......
}
for (let i = 0, len = elements.length; i < len; i++) {
const element = elements[i];
addListener(element, 'click', clicker);
}
// bad
for (let i = 0, len = elements.length; i < len; i++) {
const element = elements[i];
addListener(element, 'click', function () {});
}
类型转换
[建议] 使用 + '' 将值转换为字符串。
// good
num + '';
// bad
new String(num);
num.toString();
String(num);
[建议] 使用 + 将值转换为数字。
// good
+str;
// bad
Number(str);
[强制] 使用 parseInt 时不得省略第二个参数。
// good
parseInt(str, 10);
// bad
parseInt(str);
字符串、对象、数组
[强制] 使用 ' 而不是 " 来定义字符串。
[强制] 使用对象字面量 {} 创建普通对象。
// good
const obj = {};
// bad
const obj = new Object();
[强制] 如果对象字面量的所有属性都不需要引号,则应省略。如果必须使用引号,请使用 ' 而不是 "。
// good
const info = {
name: 'someone',
age: 28
};
// bad
const info = {
'name': 'someone',
'age': 28
};
const info2 = {
"age": 40
};
[强制] 不得修改内置对象的原型。
// Forbidden
String.prototype.trim = function () {
};
[建议] 尽量使用 . 而不是 [] 来访问对象的属性。
[建议] 使用 for ... in ... 时应当使用 hasOwnProperty,以防某些运行环境在 Object 的原型上添加了额外的属性。
const newInfo = {};
for (const key in info) {
if (info.hasOwnProperty(key)) {
newInfo[key] = info[key];
}
}
[强制] 使用数组字面量 [] 创建数组,除非是为了创建指定长度的数组。
// good
const arr = [];
const arr2 = new Array(1e4);
// bad
const arr = new Array();
[强制] 不得在数组遍历中使用 for in。
其他
[强制] 不得使用 eval 和 with。可以使用 new Function。