個人代碼規范分享


前言

本文總結了下我在前端開發過程中編寫JavaScript的一些習慣的代碼規范,以前端開發背景為主,但有些規則也適用其他語言。同時此規范並不絕對,僅供參考。

命名規范

變量長度:
變量名不要太長,盡量不超過5個單詞,若太長可以使用單詞縮寫

變量縮寫:
變量縮寫可以采用兩種縮寫方案:

1.使用單詞前幾個字母,能表述含義即可,控制在3-5個字母(具體長度自定)。如:

醫院:hosp
醫生:doc
選項:opt

2.若頁面內同時出現“文檔”和“醫生”那么doc會沖突,可以適當增加長度或變換單詞來區分。如:

文檔:docs
醫生:doct

3.使用單詞的重音字母,使人能看到字母聯想到單詞。如:

產品:pdt
配置:cfg
檢查:chk

函數命名

操作類函數:
一般使用動詞,配合各類形容詞,大致如下:
1.純動詞。如:

save()
delete()
close()

2.動詞+名詞。如:

保存醫生:saveDoc()
刪除醫院:delHosp()
創建產品:createPdt()

3.動詞+形容詞+名詞。如

刪除選中的醫生:delSelectDoc()
追加一個臨時醫院:appendTempHosp()
保存所有產品:saveAllPdt()

獲取數據類函數:
統一使用get開頭。如:

getDocList()
getDisablePdt()
getElementById(id)

從網絡獲取數據類函數:
統一使用load開頭。如:

獲取省份數據:loadProvince()
根據省份ID獲取市區數據:loadCityByProvinceId(pid)
根據市區ID獲取縣數據:loadCountyByCityId(cid)

load與get的區別個人認為在於,get更通用,可以用於代碼內部的數據處理邏輯,load更傾向於從遠程加載。

事件響應函數:
on+(動詞/操作)+元素+事件名。如

點擊保存按鈕:onSaveBtnClick()
點擊添加按鈕:onAddBtnClick()
當是否可用復選框變更時:onIsEnableChkChange()
頭像圖片鼠標移入時:onHeaderImgMouseEnter()

也可以是on+元素+(動詞/操作/用途)+事件名。如

onBtnSaveClick()
onChkIsEnableChange()

看個人習慣即可。

雖然看上去略繁瑣,但通過函數名本身,就可以完整的定位到此函數的用途。例如onIsEnableChkChange函數名:

  1. 看到on開頭,知道這是一個響應界面操作事件的函數
  2. 看到isEnable,知道這是“是否可用”的功能的元素。
  3. 看到chk,知道這是一個復選框checkbox元素的事件
  4. 看到末尾的Change,知道這是一個change事件的響應函數
  5. 綜上,看到命名,就可以聯想到網頁上有一個 名叫xxx是否可用的復選框,這是點擊了這個復選框后的事件

變量命名

變量單詞連接符:
不使用單詞連接符,使用小駝峰式命名。如

btnSaveClick

布爾值類型變量:
統一使用is開頭。如

是否可用:isEnable
是否選中:isCheck
是否刪除:isDelete

集合類型變量:
統一使用List結尾。如

食品列表:foodList
醫生列表:docList
已選產品列表:selectPdtList

數組循環體內臨時變量:
若循環體代碼量少,或僅一行lambda表達式,則可簡寫 docd, pdtp
循環體代碼量大時,或嵌套循環時,盡量使用Item結尾。如docItem, pdtItem
不強制要求,僅為區分層級關系

字典變量:
統一使用Dic(Dictionary)結尾,如

openWithDic
exeDumpDic

枚舉集合:
統一使用Enum(Enumeration)結尾。如

醫生類型枚舉:docTypeEnum
產品狀態枚舉:pdtStatusEnum
服務器狀態碼枚舉:serverCodeEnum

枚舉項:
建議使用全大寫,使用下划線連接單詞,與常量規則一致。如

服務器返回值失敗:serverCodeEnum.ERROR
服務器返回值成功:serverCodeEnum.SUCCESS 

jQuery變量:
建議使用$開頭,或J_開頭,風格統一即可。

$saveBtn
J_saveBtn

函數變量:
建議使用FnCb結尾,標明此變量為函數指針。如

鈎子函數:hookFn
響應回調函數:responseCb
回調函數:callback

常量:
統一使用全大寫字母,單詞用下划線連接。如

MAX_SIZE
TIME_OUT

類(Class)構造函數:
統一使用大駝峰式命名。如

ListView
DataTable
TableView

類私有屬性:
如果未使用TypeScript或其他強類型語言,即若沒有使用帶有訪問修飾符(publicprivate等)的語言開發,應該通過變量名本身即可區分是私有屬性還是公開屬性。
私有屬性以及私有函數,應統一以下划線開頭。如

_data
_pdtList
_getData()
_setData()

目的在於給與類的使用者可以通過變量區分,哪些是可以使用的公開屬性和方法,哪些不應該使用的私有屬性以及不應該調用的私有方法。

組件事件命名:
1.統一使用on開頭。如

onClick(e)
onSubmit(e)

2.關鍵流程類事件,應提供after事件和before事件,以onBefore和onAfter開頭。如

准備提交前事件:onBeforeSubmit
提交后事件:onAfterSubmit
准備展開前事件:onBeforeExpand
刪除后事件:onAfterDel

3.屬性/狀態變更類事件,應以on開頭,changed結尾。如

check屬性變更時事件:onCheckedChange
select屬性變更時事件:onSelectedChange
產品狀態變更時事件:onPdtStatusChange

代碼建議

  1. 善用變量緩存
  2. 重復使用多次的字符串必須緩存
  3. 善用枚舉變量,減少后期維護成本
  4. 類方法應全部掛載到原型對象
  5. 不應該使用類私有全局變量,應使用類靜態變量
  6. 盡量減少閉包代碼,以減少可能會出現的問題的概率
  7. 應堅持“先定義,后使用”的規范。以減少js默認的定義提升的坑
  8. 整個代碼應該應只有一個入口函數,即創建一個init函數,來執行所有初始代碼,而不是整篇代碼隨定義,隨執行
  9. 事件綁定類函數應放在同一處執行,減少維護成本
  10. 善用#region 創建代碼塊,不同功能的代碼歸類,初始化類,事件綁定類,界面交互類,純數據處理工具類等。
  11. 模塊類文件,所有導出變量應全部定義在尾部。方便查閱
  12. 盡可能不創建全局變量,不注冊全局事件,為后期方便轉型為單頁應用
  13. 盡量將代碼純數據邏輯與界面交互邏輯分開,方便后期寫測試用例
  14. 盡量將所有變更定義放置在 文件/函數 內頂部
  15. 善用try catch和throw Error
  16. 不要在數組內存放不同類型的數據,一個數組應只存放一種數據類型變量,方便強類型識別與糾錯
  17. 盡可能不要創建類數組變量
  18. 盡可能不使用eval、with
  19. 多寫注釋!推薦jsdoc風格注釋,方便一鍵抽取注釋生成代碼文檔
  20. 推薦使用flowjs或ts等類型描述語言來約束、規范、糾錯和智能感知。

附:關於js中的對象、字典與枚舉的關系

以上個人經驗在組內分享時,有同學提出疑問:

為什么會有字典變量,以及枚舉變量,這從本質上不都是Object對象么?

關於這個問題我是這么理解的,在js中確實對象是最強大的,任何在其他語言當中的類似對象的數據結構,在js里都可以是對象。但也正因為如此寬泛,讓我們的使用過程中會產生一些疑惑或誤解,才需要對各種的對象做分類。
所以回過頭來再說對象字典枚舉的關系。

他們的相同點:
他們都是鍵值對集合(KeyValuePair)
他們的Key都不能重復

他們的不同點:
對象:
對象的的Key可以是字符串類型或數值類型。如果同時包含這兩種就類數組對象,比如document.getElementBy...系列函數的返回值:HTMLCollection,再比如HTML元素的子元素集合:NodeList,以及HTML元素的屬性值:NamedNodeMap,等都是類數組對象。
對象的Value的類型,可以是任意類型。而且是在一個對象變量中的Value都可以是任意類型,如JSON對象。

字典:
而字典的Key一定是字符串類型的(其他語言中不是,受限於js語言),字典的Value也可以任意類型,但在一個字典對象變量中的所有Value一定是相同類型,也就是說字典其實是個Object<string, TValue>
例:比如前面剛剛提到的HTML元素的attributes屬性值:NamedNodeMap,就是應該一個典型的字典對象:它屬於Dictionary<string, Attr>
但是奇葩的是NamedNodeMap也支持數組下標式訪問,所以它同時也是一個List<Attr>,在js里只能歸結於他是類數組對象的范疇內了。

枚舉:
而最后的枚舉對象的范圍會更小,枚舉的值一般為基本數據類型,在其他語言中甚至只能是數值類型。
例如,定義一個枚舉對象用於一組常量:

// 服務器接口返回值狀態碼枚舉
var serverCodeEnum = {
    SUCCESS : 0,
    ERROR : 1,
    XXXXX : 2,
    XXXXX : 3,
}

TypeScript中的枚舉變量

在TypeScript為了照顧js語言的日常使用,把enum關鍵字的編譯后代碼做成了雙向訪問的類數組對象。
也就是既可以用過名稱獲得數值,也可以通過數值獲得名稱。使用非常方便:

【TypeScript代碼中的枚舉】
enum ownerTypeEnum {
    public = 0,
    private
}

【編譯為JS后的代碼】
var ownerTypeEnum;
(function (ownerTypeEnum) {
    ownerTypeEnum[ownerTypeEnum["public"] = 0] = "public";
    ownerTypeEnum[ownerTypeEnum["private"] = 1] = "private";
})(ownerTypeEnum || (ownerTypeEnum = {}));

// 效果:
// ownerTypeEnum.private -> 1
// ownerTypeEnum[1] -> "private"

最后

此類文章非常容易引戰,所以再次聲明以上僅個人習慣以及經驗的分享,每個人都有自己的習慣,不管采用哪種習慣其實都可以。
至少應該在組內,或是某項目內的所有成員都采用相同的一套規范,做到見名知意。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM