一、變量相關(guān)
1、變量命名
// bad: 自我感覺良好的縮寫
let fName = 'jackie' // 看起來命名挺規(guī)范,縮寫,駝峰法都用上,ESlint各種檢測(cè)規(guī)范的工具都通過,But,fName是啥?這時(shí)候,你是不是想說What are you 弄啥呢?
let lName = 'willen' // 這個(gè)問題和上面的一樣
// good: 無需對(duì)每個(gè)變量都寫注釋,從名字上就看懂
let firstName = 'jackie'
let lastName = 'willen'
// bad: 命名過于啰嗦
let nameValue
let theUsers
// good: 做到簡(jiǎn)潔明了
let name
let users
2、特定的變量
// bad: 無說明的參數(shù)
if (value.length < 8) { // 為什么要小于8,8表示啥, 為啥不是4、6
....
}
// good: 添加變量
const MAX_INPUT_LENGTH = 8
if (value.length < MAX_INPUT_LENGTH) { // 一目了然,不能超過最大輸入長(zhǎng)度
....
}
二、函數(shù)相關(guān)
1、函數(shù)命名
// bad: 無法從函數(shù)名得知返回值類型
function showFriendsList() { // 不知道是返回一個(gè)數(shù)組,還是返回一個(gè)boolean值
....
}
// good: 對(duì)于返回true or false的函數(shù),最好以should/is/can/has開頭
function shouldShowFriendsList() {...}
function isEmpty() {...}
function canCreateDocuments() {...}
function hasLicense() {...}
// bad: 無法辨別函數(shù)意圖
function param(json) { // param要做什么,無法得知
}
// good: 函數(shù)要以動(dòng)詞開頭,動(dòng)名結(jié)構(gòu)
function convertObj2QueryString(json) {
}
2、一個(gè)函數(shù)做一件事情,不要一個(gè)函數(shù)混雜多個(gè)功能
// bad
function sendEmailToClients(clients) {
clients.forEach(client => {
const clientRecord = database.lookup(client)
if (clientRecord.isActive()) {
email(client)
}
})
}
// good
function sendEmailToActiveClients(clients) { //各個(gè)擊破,易于維護(hù)和復(fù)用
clients.filter(isActiveClient).forEach(email)
}
function isActiveClient(client) {
const clientRecord = database.lookup(client)
return clientRecord.isActive()
}
3、函數(shù)中過多的采用if else ..
// bad
if (a === 1) {
...
} else if (a ===2) {
...
} else if (a === 3) {
...
} else {
...
}
// good 可以使用switch替代
switch(a) {
case 1:
....
case 2:
....
case 3:
....
default:
....
}
// good 用映射的方式
let handler = {
1: () => {....},
2: () => {....}.
3: () => {....},
default: () => {....}
}
handler[a]() || handler['default']()
// bad
function(err, results) {
if (!err) {
doOtherStuff()
doMoreStuff()
// ... etc
// ... etc
} else {
handleError(err)
}
}
// good 避免多余的Else, 盡早Return
function(err, results) {
if (err) {
handleError(err)
}
doOtherStuff()
doMoreStuff()
// ... etc
// ... etc
}
三、盡量使用ES6或ES7語法
1、連接字符串
// bad 使用傳統(tǒng)+號(hào)
let message = 'Hello ' + name + ', it\'s ' + time + ' now'
// good 采用模板字符
let message = `Hello ${name}, it's ${time} now`
2、使用解構(gòu)賦值
// bad 使用傳統(tǒng)賦值
var data = { name: 'dys', age: 1 };
var name = data.name;
var age = data.age;
var fullName = ['jackie', 'willen'];
var firstName = fullName[0];
var lastName = fullName[1];
// good 使用結(jié)構(gòu)賦值
const data = {name:'dys', age:1};
const {name, age} = data; // 怎么樣,是不是簡(jiǎn)單明了
let fullName = ['jackie', 'willen'];
const [firstName, lastName] = fullName;
四、關(guān)于注釋
以下情景,使用注釋較好:
1、彌補(bǔ)代碼表達(dá)意圖的失敗
代碼本身無法說明意圖,這時(shí)使用注釋,說明這段代碼需要被修改
2、提供信息
提供代碼以外的信息,比如產(chǎn)品相關(guān)信息
3、復(fù)雜實(shí)現(xiàn)的簡(jiǎn)要概括
讓閱讀者快速了解某個(gè)復(fù)雜的系統(tǒng)
4、警示、提醒
比如某個(gè)不起眼的代碼是為了解決某個(gè) bug,防止別人誤刪
5、TODO
提醒某些地方有功能或者優(yōu)化未做,改好后盡快刪除
以下是不好的注釋:
1、令人費(fèi)解的注釋
讀懂花費(fèi)的時(shí)間比看代碼的時(shí)間還長(zhǎng)
2、誤導(dǎo)性注釋,老舊的注釋
代碼才是真相,注釋有可能是謊言,還是要“少寫注釋!”
3、廢話注釋
變量名、函數(shù)名已經(jīng)很清晰,就不需要注釋;因?yàn)榇a會(huì)經(jīng)常修改,但是注釋,經(jīng)常會(huì)缺乏維護(hù),極有可能最后注釋和代碼本身已經(jīng)相去甚遠(yuǎn)
4、注釋掉的代碼
沒用的代碼及時(shí)刪除
別給糟糕的代碼寫注釋,重構(gòu)!
總結(jié):代碼整潔之道,相信有個(gè)幾年經(jīng)驗(yàn)的都會(huì)知道,但是因?yàn)榉N種原因,常常無法遵守。希望在今后的日子里,我們能盡量試著使自己代碼的可讀性和可維護(hù)性更高,這樣代碼質(zhì)量更好,更容易定位bug,加快效率,也是對(duì)個(gè)人的一種提升。與君共勉。