#### **縮進**
* [強制] 使用 4 個空格做為一個縮進層級,不允許使用 2 個空格 或 tab 字符。
* [強制] 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;
```
* [強制] 用作代碼塊起始的左花括號 { 前必須有一個空格。
```
// good
if (condition) {
}
while (condition) {
}
function funcName() {
}
// bad
if (condition){
}
while (condition){
}
function funcName(){
}
```
* [強制] if / else / for / while / function / switch / do / try / catch / finally 關鍵字后,必須有一個空格。
```
// good
if (condition) {
}
while (condition) {
}
(function () {
})();
// bad
if(condition) {
}
while(condition) {
}
(function() {
})();
```
* [強制] 在對象創建時,屬性中的 : 之后必須有空格,: 之前不允許有空格。
```
// good
var obj = {
a: 1,
b: 2,
c: 3
};
// bad
var obj = {
a : 1,
b:2,
c :3
};
```
* [強制] 函數聲明、具名函數表達式、函數調用中,函數名和 ( 之間不允許有空格。
```
// good
function funcName() {
}
var funcName = function funcName() {
};
funcName();
// bad
function funcName () {
}
var funcName = function funcName () {
};
funcName ();
```
* [強制] , 和 ; 前不允許有空格。如果不位于行尾,, 和 ; 后必須跟一個空格。
```
// good
callFunc(a, b);
// bad
callFunc(a , b) ;
```
* [強制] 在函數調用、函數聲明、括號表達式、屬性訪問、if / for / while / switch / catch 等語句中,() 和 [] 內緊貼括號部分不允許有空格。
```
// 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
var arr1 = [];
var arr2 = [1, 2, 3];
var obj1 = {};
var obj2 = {name: 'obj'};
var obj3 = {
name: 'obj',
age: 20,
sex: 1
};
// bad
var arr1 = [ ];
var arr2 = [ 1, 2, 3 ];
var obj1 = { };
var obj2 = { name: 'obj' };
var obj3 = {name: 'obj', age: 20, sex: 1};
```
* [強制] 行尾不得有多余的空格。
#### **換行**
* [強制] 每個獨立語句結束后必須換行。
* [強制] 每行不得超過 120 個字符。
* 超長的不可分割的代碼允許例外,比如復雜的正則表達式。長字符串不在例外之列。
* [強制] 運算符處換行時,運算符必須在新行的行首。
```
// good
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
|| user.hasAuthority('delete-admin')
) {
// Code
}
var result = number1 + number2 + number3
+ number4 + number5;
// bad
if (user.isAuthenticated() &&
user.isInRole('admin') &&
user.hasAuthority('add-admin') ||
user.hasAuthority('delete-admin')) {
// Code
}
var result = number1 + number2 + number3 +
number4 + number5;
```
* [強制] 在函數聲明、函數表達式、函數調用、對象創建、數組創建、for 語句等場景中,不允許在 , 或 ; 前換行。
```
// good
var obj = {
a: 1,
b: 2,
c: 3
};
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
// bad
var obj = {
a: 1
, b: 2
, c: 3
};
foo(
aVeryVeryLongArgument
, anotherVeryLongArgument
, callback
);
```
* [建議] 不同行為或邏輯的語句集,使用空行隔開,更易閱讀。
```
// 僅為按邏輯換行的示例,不代表setStyle的最優實現
function setStyle(element, property, value) {
if (element == null) {
return;
}
element.style[property] = value;
}
```
* [建議] 在語句的行長度超過 120 時,根據邏輯條件合理縮進。
```
// 較復雜的邏輯條件組合,將每個條件獨立一行,邏輯運算符放置在行首進行分隔,或將部分邏輯按邏輯組合進行分隔。
// 建議最終將右括號 ) 與左大括號 { 放在獨立一行,保證與 `if` 內語句塊能容易視覺辨識。
if (user.isAuthenticated()
&& user.isInRole('admin')
&& user.hasAuthority('add-admin')
|| user.hasAuthority('delete-admin')
) {
// Code
}
// 按一定長度截斷字符串,并使用 + 運算符進行連接。
// 分隔字符串盡量按語義進行,如不要在一個完整的名詞中間斷開。
// 特別的,對于 HTML 片段的拼接,通過縮進,保持和 HTML 相同的結構。
var html = '' // 此處用一個空字符串,以便整個 HTML 片段都在新行嚴格對齊
+ '<article>'
+ '<h1>Title here</h1>'
+ '<p>This is a paragraph</p>'
+ '<footer>Complete</footer>'
+ '</article>';
// 也可使用數組來進行拼接,相對 `+` 更容易調整縮進。
var html = [
'<article>',
'<h1>Title here</h1>',
'<p>This is a paragraph</p>',
'<footer>Complete</footer>',
'</article>'
];
html = html.join('');
// 當參數過多時,將每個參數獨立寫在一行上,并將結束的右括號 ) 獨立一行。
// 所有參數必須增加一個縮進。
foo(
aVeryVeryLongArgument,
anotherVeryLongArgument,
callback
);
// 也可以按邏輯對參數進行組合。
// 最經典的是 baidu.format 函數,調用時將參數分為“模板”和“數據”兩塊
baidu.format(
dateFormatTemplate,
year, month, date, hour, minute, second
);
// 當函數調用時,如果有一個或以上參數跨越多行,應當每一個參數獨立一行。
// 這通常出現在匿名函數或者對象初始化等作為參數時,如 `setTimeout` 函數等。
setTimeout(
function () {
alert('hello');
},
200
);
order.data.read(
'id=' + me.model.id,
function (data) {
me.attchToModel(data.result);
callback();
},
300
);
// 鏈式調用較長時采用縮進進行調整。
$('#items')
.find('.selected')
.highlight()
.end();
// 三元運算符由3部分組成,因此其換行應當根據每個部分的長度不同,形成不同的情況。
var result = thisIsAVeryVeryLongCondition
? resultA : resultB;
var result = condition
? thisIsAVeryVeryLongResult
: resultB;
// 數組和對象初始化的混用,嚴格按照每個對象的 `{` 和結束 `}` 在獨立一行的風格書寫。
var array = [
{
// ...
},
{
// ...
}
];
```
* [建議] 對于 if...else...、try...catch...finally 等語句,推薦使用在 } 號后添加一個換行 的風格,使代碼層次結構更清晰,閱讀性更好。
```
if (condition) {
// some statements;
}
else {
// some statements;
}
try {
// some statements;
}
catch (ex) {
// some statements;
}
```
#### **語句**
* [強制] 不得省略語句結束的分號。
* [強制] 在 if / else / for / do / while 語句中,即使只有一行,也不得省略塊 {...}。
```
// good
if (condition) {
callFunc();
}
// bad
if (condition) callFunc();
if (condition)
callFunc();
```
* [強制] 函數定義結束不允許添加分號。
```
// good
function funcName() {
}
// bad
function funcName() {
};
// 如果是函數表達式,分號是不允許省略的。
var funcName = function () {
};
```