網址:https://blog.csdn.net/sinat_17775997/article/details/80756358
## 縮進
4個空格,避免使用 `Tab`
下面是正確的做法

下邊是正確的做法

```
if (true) {
doSomething();
}
```
2.行的長度
每行長度不應該超過80個字符.如果一行多于80個字符,應當在一個運算符(逗號,加好等)后換行.下一級應當增加兩級縮進(8個字符).
```
// 好的寫法
doSomething(arg1, arg2, arg3, arg4,
arg5);
// 不好的寫法: 第二行只有4個空格的縮進
doSomething(arg1, arg2, arg3, arg4,
arg5);
// 不好的寫法: 在運算符之前換行
doSomething(arg1, arg2, arg3, arg4
,arg5);
```
## 3.原始值
特殊值`null`除了下述情況應當避免使用
用來初始化一個變量,這個變量可能被賦值為一個對象
用來和一個已經初始化的變量比較,這個變量可以是也可以不是一個對象
當函數的參數期望是對象時,被用作返回值傳出
```
// 好的做法
const person = null;
判斷一個變量是否定義應當使用 typeof 操作符
// 好的寫法
if (typeof constiable == 'undefined') {
// do something
}
// 不好的寫法
if (constiable == 'undefined') {
// do something
}
```
## 4.運算符間距
二元運算符前后必須使用一個空格來保持表達式的整潔.操作符包括賦值運算符和邏輯運算符
```
// 好的寫法
const found = (values[i] === item);
// 不好的寫法: 丟失了空格
const found = (values[i]===item);
// 好的寫法
if (found && (count > 10)) {
doSomething();
}
// 不好的寫法: 丟失了空格
if (found&&(count>10)) {
doSomething();
}
// 好的寫法
for(let i = 0; i < count; i++) {
process(i);
}
// 不好的寫法: 丟失了空格
for(let i=0; i<count; i++) {
process(i);
}
```
## 5.括號間距
當使用括號時,緊接左括號之后和緊接右括號之前不應該有空格
```
// 好的寫法
const found = (values[i] === item);
// 不好的寫法: 左括號之后有額外的空格
const found = ( values[i] === item);
// 好的寫法
if (found && (count > 10)) {
doSomething();
}
// 不好的寫法: 右括號之后有額外的空格
if (found && (count > 10) ) {
doSomething();
}
// 好的寫法
for(let i = 0; i < count; i++) {
process(i);
}
// 不好的寫法: 參數兩邊有額外的空格
for(let i = 0; i< count; i++) {
process( i );
}
```
## 6.對象直接量
對象直接量應當使用如下格式
起始左花括號應當同表達式保持同一行
每個屬性的名值對應當保持一個縮進,第一個屬性應當在左花括號后另起一行.
每個屬性的名值對應當使用不含引號的屬性名,其后緊跟一個冒號(之前不含空格),而后是值
倘若屬性值是函數類型,函數體應當在屬性名之下另起一行,而且其前后均應保留一個空行
一組相關的屬性前后可以插入空行以提高代碼的可讀性
結束的右花括號應當獨占一行
```
// 好的寫法
const object = {
key1: value1,
key2: value2,
func: function() {
},
key3: value3,
};
// 不好的寫法: 不恰當的縮進
const object = {
key1: value1,
key2: value2,
};
// 不好的寫法:函數體缺少空行
const object = {
key1: value1,
key2: value2,
func: function() {
},
key3: value3,
};
當對象字面量作為函數參數時,如果值是變量,起始花括號應當同函數名在同一行.所有其余先前列出的規則同樣適用
// 好的寫法
doSomething({
key1: value1,
key2: value2,
});
// 不好的寫法
doSomething({ key1: value1, key2: value2 });
```
## 7.注釋
頻繁地適用注釋有助于他人理解你的代碼.如下情況應當使用注釋
代碼晦澀難懂
可能被誤認為錯誤的代碼
必要但不明顯的針對特定瀏覽器的代碼
對于對象,方法或者屬性,生成文檔是有必要的(使用恰當的文檔注釋).
### 1).單行注釋
使用單行注釋當用來說明一行代碼或者一組代碼.單行注釋可能有三種使用方式
獨占一行的注釋,用來解釋下一行代碼
在代碼行的尾部的注釋,用來解釋它之前的代碼
多行,用來注釋掉一個代碼塊
```
// 好的寫法
if (condition) {
// 如果代碼執行到這里,則說明通過了所有的安全性檢測
allowed();
}
// 不好的寫法:注釋之前沒有空行
if (condition) {
// 如果代碼執行到這里,則說明通過了所有的安全性檢測
allowed();
}
// 不好的寫法: 錯誤的縮進
if (condition) {
// 如果代碼執行到這里,則說明通過了所有的安全性檢測
allowed();
}
// 不好的寫法: 這里應當用多行注釋
// 接下來的這段代碼非常難, 那么,讓我詳細的解釋一下
// 1. xxxx
// 2. xxxx
if (condition) {
// 如果代碼執行到這里,則說明通過了所有的安全性檢測
allowed();
}
對于代碼行尾單行注釋的情況,應確保代碼結尾同注釋之間至少一個縮進
// 好的寫法
const result = something + somethingElse; // somethingElse will never be null
// 不好的寫法: 代碼和注釋間沒有足夠的空格
const result = something + somethingElse;// somethingElse will never be null
注釋一個代碼塊時在連續多行使用單行注釋是唯一可以接受的情況.多行注釋不應當在這種情況下使用
// 好的寫法
// if(condition) {
// doSomething();
// }
```
### 2).多行注釋
多行注釋應當在代碼需要更多文字去解釋的時候使用.每個多行注釋都至少有如下三行.1.首行僅僅包括 /* 注釋開始.該行不應當有其他文字2.接下來的行以 * 開頭并保持左對齊.這些行可以由文字描述3.最后一行以 */開頭并同先前行保持對齊.也不應當有其他文字
多行注釋的首行應當保持同它描述代碼的相同層次的縮進.后續的每行應當有同樣層次的縮進并附加一個空格(為了適當保持 * 字符的對齊).每一個多行代碼之前應當預留一個空格
```
// 好的寫法
if (condition) {
/*
* 如果代碼執行到這里
* 說明通過了所有的安全性檢測
*/
allowed();
}
// 不好的寫法: 注釋之前無空行
if (condition) {
/*
* 如果代碼執行到這里
* 說明通過了所有的安全性檢測
*/
allowed();
}
// 不好的寫法: 星號后沒有空格
if (condition) {
/*
*如果代碼執行到這里
*說明通過了所有的安全性檢測
*/
allowed();
}
// 不好的寫法: 錯誤的縮進
if (condition) {
/*
* 如果代碼執行到這里
* 說明通過了所有的安全性檢測
*/
allowed();
}
// 不好的寫法: 代碼尾部注釋不要用多行注釋格式
const result = something + somethingElse; /* somethingElse 不應當取值為null */
```
### 3)注釋聲明
注釋有時候可以用來給一段代碼聲明額外的信息.這些聲明的格式以單個單詞打頭并緊跟一個雙引號.可使用的聲明如下
`TODO`: 說明代碼還未完成.應當包含下一步要做的事情
`HACK`: 表明代碼實現走了一個捷徑
`XXX`: 說明代碼是有問題的并應當盡快修復
`FIXME`: 說明代碼是有問題的并應當盡快修復.重要性略次于XXX
`REVIEW`: 說明代碼任何可能的改動都需要評審這些聲明可能在一行或多行注釋中使用,并且應當遵循同一般注釋類型相同的格式規則
```
// 好的寫法
// TODO: 我希望找到一種更快的方式
doSomething();
// 不好的寫法: 注釋聲明空格不正確
// TODO : 我希望找到一種更快的方式
doSomething();
// 好的寫法
// REVIEW: 有更好的方法嗎?
doSomething();
// 不好的寫法: 代碼和注釋應當保持同樣的縮進
// REVIEW: 有更好的方法嗎?
doSomething();
```
## 8.命名
變量命名應當采用駝峰命名格式,首字母小寫,每個單詞首字母大寫.變量名的第一個單詞應當是一個名詞(而非動詞)比避免同函數混淆.不要在變量名中使用下劃線
```
// 好的寫法
const myName = 'Jack';
// 不好的寫法: 大寫字母開頭
const MyName = 'Jack';
// 不好的寫法: 動詞開頭
const getMyName = 'Jack';
// 不好的寫法: 使用下劃線
const my_name = 'Jack';
函數命名應當采用駝峰命名格式.函數名的第一個單詞應當是動詞(而非名詞)來避免同變量混淆.函數名中最好不要使用下劃線.
// 好的寫法
function doSomething() {
// 代碼
}
// 不好的寫法: 大寫字母開頭
function DoSomething() {
// 代碼
}
// 不好的寫法: 名詞開頭
function car() {
// 代碼
}
// 不好的寫法: 使用下劃線
function do_something() {
// 代碼
}
構造函數--通過new元素安撫創建新對象的函數--也應使用駝峰合適命名,首先首字母大寫.構造函數命名應當以非動詞開頭,因為new代表著創建一個對象實例的操作
// 好的寫法
function MyObject() {
}
// 不好的寫法: 小寫字母開頭
function myObject() {
}
// 不好的寫法: 使用下劃線
function My_Object() {
}
// 不好的寫法: 動詞開頭
function getMyObject() {
}
```
常量(不會被改變的變量)的命名應當是所有字母大寫,不同單詞之間用單個下劃線隔開.ES6中使用const來聲明一個常量
```
// 好的寫法
const TOTAL_COUNT = 10;
// 不好的寫法
const totalCount = 10;
// 不好的寫法: 混合模式
const total_COUNT = 10;
對象的屬性同變量的命名規范相同.對象的方法同函數的命名規則相同.如果屬性或者方法是私有的,應當在之前加一個下劃線
// 好的寫法
const object = {
_count: 10,
_getCount: function() {
return this._count;
}
}
```
## 9.賦值
當給變量賦值時,如果右側是含有比較語句的表達式,需要用圓括號包裹
```
// 好的寫法
const flag = (i < count);
// 不好的寫法:遺漏圓括號
const flag = i < count;
10.等號運算符
使用 === (嚴格相等) 和 !==(嚴格不相等)代替 ==(相等) 和 !=(不等) 來避免弱類型轉換錯誤
// 好的寫法
const same = (a === b);
// 不好的寫法: 使用 ==
const same = (a == b);
```
## 11.三元操作符
三元運算符應當僅僅用在條件賦值語句中,而不要作為if語句的替代品.
```
// 好的寫法
const value = condition ? value1 : value2;
// 不好的寫法: 沒有賦值,應當使用 if 表達式
condition ? doSomething() : doSomethingElse();
```
## 12.語句
### 簡單語句
每一行最多只包含一條語句.所有簡單的語句都應該以分號(;)結束.
```
// 好的寫法
const a = 1;
const b = 2;
const c = a + b;
// 不好的寫法: 多個表達式寫在一行
const a = 1;const b = 2;const c = a + b;
```
### 返回語句
返回語句當返回一個值的時候不應當使用圓括號包裹,除非在某些情況下這么做可以讓返回值更容易理解.例如:
```
return;
return collection.size();
return (size > 0 ? size : defaultSize)
```
### 復合語句
復合語句是大括號括起來的語句列表;
括起來的語句應當較復合語句多縮進一個層級
開始的大括號應當在復合語句所在行的末尾;結束的大括號應當獨占一行且同復合語句的開始保持同樣的縮進.
當括號時控制結構的一部分時,諸如if或者for語句,所有語句都需要用打括號括起來,也包括單個語句.這個約定使得我們更方便地添加語句而不用擔心忘記加括號而引起bug
像if一樣的語句開始的關鍵詞,其后應當緊跟一個空格,起始大括號應當在空格之后
### if語句
```
if (condition) {
statements
} else if (condition) {
statements
} else {
statements
}
```
絕不允許在if語句中省略花括號
```
// 好的寫法
if (condition) {
doSomething();
}
// 不好的寫法: 不恰當的空格
if(condition){
doSomething();
}
// 不好的寫法: 遺漏花括號
if (condition)
doSomething();
// 不好的寫法: 所有代碼寫在一行
if (condition) { doSomething(); }
// 不好的寫法: 所有代碼寫在一行且沒有花括號
if (condition) doSomething();
```
### for語句
```
for (initialization; condition; update) {
statements
}
for (constiable in object) {
statements
}
```
當使用 for-in 語句時,記得使用 hasOwnProperty() 進行雙重檢查來過濾出對象的成員
### while語句
```
while (condition) {
statements
}
```
### do語句
```
do {
statements
} while (condition)
```
### switch語句
```
switch (expression) {
case expression:
statements
default:
statements
}
```
switch下的每一個case都叮當保持一個縮進.除第一個之外包括default在內的每一個case都應當在之前保持一個空行每一組語句(除了default)都應當以break, return, throw結尾,或者用一行注釋表示跳過
```
// 好的寫法
switch (value) {
case 1:
/* falls through */
case 2:
doSomething();
break;
case 3:
return true;
default:
throw new Error('this should not happen');
}
```
### try語句
```
try {
statements
} catch (constiable) {
statements
} finally {
statements
}
```
## 13.嚴格模式
嚴格模式應當僅限在函數內部使用,千萬不要在全局使用.
ES6 的模塊自動采用嚴格模式,不管你有沒有在模塊頭部加上`"use strict"`;。
## 14.變量聲明
所有的變量在使用前都應事先定義.變量定義應放在函數開頭.變量定義前應當初始化,并且賦值操作符應當保持一致的縮進.初始化的變量應當在未初始化變量之前.
推薦使用ES6的let和 const來聲明變量
## 15.函數聲明
函數聲明應當在使用前提前定義.一個不是作為方法的函數(也就是沒有作為一個對象的屬性)應當使用函數定義的格式(不是函數表達式和Function構造器格式).函數名和開始圓括號之前不應當有空格.結束的圓括號和右邊的花括號之間應該留一個空格.右側的花括號應當同function關鍵字保持同一行.開始和結束括號之間不應該有空格.參數名之間應當在逗號之后保留一個空格.函數體應當保持一級縮進
```
// 好的寫法
function doSomething(arg1, agr2) {
return arg1 + arg2;
}
// 不好的寫法: 第一行不恰當的空格
function doSomething (arg1, agr2) {
return arg1 + arg2;
}
// 不好的寫法:
const doSomething = function doSomething(arg1, agr2) {
return arg1 + arg2;
}
// 不好的寫法: 左側的花括號位置不對
function doSomething(arg1, agr2)
{
return arg1 + arg2;
}
// 錯誤的寫法: 使用Function構造器
const doSomething = new Function('arg1', 'agr2', 'return arg1 + arg2');
```
## 16.留白
在邏輯相關的代碼塊之間添加空行可以提高代碼的可讀性
兩行空行權限在如下情況使用
在不同的源代碼文件之間
在類和接口定義之間
單行空行權限在如下情況使用
方法之間
方法中局部變量和第一行語句之間
多行或單行注釋之前
方法中邏輯代碼塊之間以提高代碼的可讀性
空格應當在如下情況中使用
關鍵詞后跟括號的情況應當用空格隔開
參數列表中逗號之后應當保留一個空格
所有的除了點(.)之外的二元運算符,其操作數都應當用空格隔開.單目運算符的操作數之間不應該用空白隔開,諸如一元減號,遞增(++),遞減(--)
for語句中的表達式之間應當用空格隔開
## 17. 需要避免的
切勿使用像`String`一類的原始包裝類型創建的新對象
避免使用`eval()`
避免使用`with`語句.改語句在嚴格模式中不復存在,可能在未來也將去除
## 使用工具(`eslint`)來強制約束
eslint 規則
eslint規則在.eslintrc.js中定義,覺得不合理的可以禁掉某條規則,或者有好的建議的也可以添加;主要注意一下幾條:
代碼縮進用4空格
語句必須默認后加分號
使用單引號
提交代碼前將console.log語句刪掉或注釋掉(不然影響其他開發人員調試)
禁止使用const,使用es6的let,const聲明變量
還有一些情況是不需要檢測的,例如第3方的庫, 框架、組件、ui庫等等,可以將這些文件放在.eslintignore文件中,可以忽略eslint的檢測
在文件頂部加上下面這行,可以禁掉整個文件的eslint規則
```
/* eslint-disable */
```
pre-commit
代碼提交之前會強制code-review,不符合規范的不允許提交代碼使用方法1.在命令行安裝
```
npm i --save-dev pre-commit
```
2.在package.json中配置
```
{
"scripts": {
"eslint": "eslint ./ --ext js,vue --ignore-pattern .eslintignore --cache --fix",
"lint-message": "echo '開始 eslint 檢查, 存在 error 則會拒絕提交'"
},
"pre-commit": [
"lint-message",
"eslint" // 進行eslint檢查并自動修復一些簡單的格式錯誤
],
}
```
代碼提交之前會強制code-review,不符合規范的不允許提交代碼
如果項目實在沒時間去改的話,可以 `git commit -m 'XXX' --no-verify` 或 `git commit -n 'xxx'` 強制提交
小技巧-vscode可以配置保存自動修復eslint錯誤
vscode安裝eslint插件,在配置中配置如下
```
{
"eslint.autoFixOnSave": true,
"eslint.enable": true,
"eslint.options": {
"extensions": [".js", ".vue", ".jsx"]
},
"eslint.validate": [
{
"language": "vue",
"autoFix": true
},
{
"language": "javascript",
"autoFix": true
},
{
"language": "javascriptreact",
"autoFix": true
}
],
}
```
配置完成之后,每次保存,都會自動根據 .eslintrc.js文件自動修復空格,分號的錯誤;但是最好還是在平常的編碼中養成一個良好的習慣,而不是依賴工具.
下列參考給出的文章及書籍,有時間一定要好好看一下,會幫助大家深刻理解JavaScript編碼風格的重要性。永遠記住,規范能解決大部分問題。
## 參考
* 編寫可維護的JavaScript
* 編寫高質量代碼:Web前端開發修煉之道
* 代碼整潔之道
* ESLint
* JavaScript編碼風格
作者:funnycoderstar
鏈接:https://juejin.im/post/5b2903ce51882574a86cd288
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
- javascript封裝
- jquery封裝
- layui封裝
- 基本知識
- 匿名函數
- 嚴格模式
- 代碼規范工具
- 使用JSHint和JSLint
- 構建
- Grunt
- gulp
- Gulp使用入門操作十一步壓縮JS
- 注意
- 初級
- 中級
- 高級
- 將es6代碼轉成es5
- 我常用的
- 報錯處理
- 《編寫可維護的Javascript》
- 第1章:基本的格式化
- 縮進層級
- 語句結尾
- 行的長度
- 換行
- 空行
- 命名
- 變量和函數
- 常量
- 構造函數
- 直接量
- 第2章:注釋
- 單行注釋
- 多行注釋
- 使用注釋
- 文檔注釋
- 第3章:語句和表達式
- 花括號的對齊方式
- 塊語句間隔
- switch語句
- 第4章:變量函數運算符
- 變量聲明
- 函數聲明
- 函數調用間隔
- 立即調用函數
- 嚴格的模式
- 相等
- 第5章:UI的松耦合
- 什么是松耦合
- 將javascript從css中抽離
- 將css從javascript中抽離
- 將javascript從html中抽離
- 將html從javascript中抽離
- 第6章:避免使用全局變量
- 全局變量帶來的問題
- 意外的全局變量
- 單全局變量方式
- 零全局變量
- 第7章:事件處理
- 典型用法
- 規則1:隔離應用邏輯
- 規則2:不要分發事件對象
- 第8章:避免“空比較”
- 檢測原始值
- 檢測應用值
- 檢測屬性
- 第9章:將配置數據從代碼中分離出來
- 什么是配置數據
- 抽離配置數據
- 保存配置數據
- 第10章:拋出自定義錯誤
- 錯誤的本質
- 在javascript拋出錯誤
- 拋出錯誤的好處
- 何時拋出錯誤
- try-catch語句
- 錯誤類型
- 第11章:不是你的對象不要動
- 什么是你的
- 原則
- 更好的途徑
- 關于Polyfill的注釋
- 阻止修改
- 第12章:瀏覽器嗅探
- User-Agent嗅探
- 特性檢測
- 避免特性推斷
- 避免瀏覽器推斷
- 應當如何取舍
- 第13章:目錄和文件結構
- 最佳實踐
- 基本結構
- 第14章:Ant
- 安裝
- 配置文件
- 執行構建
- 目標操作的依賴
- 屬性
- Buildr項目
- 第15章:校驗
- 查找文件
- 任務
- 增強的目標操作
- 其他方面的改進
- Buidr任務
- 第16章:文件的合并與加工
- 任務1
- 行尾結束符
- 文件頭和文件尾
- 加工文件
- 第17章:文件的精簡與壓縮
- 文件精簡
- 壓縮
- 第18章:文檔化
- JSDoc Toolkit
- YUI DOC
- 第19章:自動化測試
- YUI Test Selenium引擎
- Yeti
- PhantomJS
- JsTestDriver
- 第20章:組裝到一起
- Javascript編碼風格指南