前端程式碼編碼和設計規範系列——JavaScript程式設計規範
1文件資訊
條目 |
內容 |
專案編號 |
通用 |
專案名稱 |
通用 |
標題 |
JavaScript程式設計規範 |
類別 |
規範文件 |
當前 |
試用草稿 |
摘要 |
|
當前版本 |
V1.0 |
日期 |
2015/11/9 |
作者 |
徐維堅(xuweijian) |
文件擁有者 |
內部公開 |
檔案 |
前端規範系列-JavaScript篇.docx |
2修改歷史
編號 |
修訂人 |
修訂內容簡述 |
修訂 日期 |
修訂前 版本號 |
修訂後 版本號 |
V0001 |
徐維堅 |
程式設計規範檔案編寫,草稿試用版公佈 |
2015/11/10 |
V1.0 |
規範前言
良好的程式設計規範對於軟體的開發與維護,至關重要!他不僅可以提高程式碼的可讀性、可靠性、有效性、健壯性,而且利於幫助開發人員開發和維護程式碼。對於一個團隊協作的專案來說,人員的變動,一個良好的程式設計規範,有助於後續開發者和新手快速瞭解專案程式碼所要表現的含義。
1 範圍
本規範規定了使用JavaScript語言程式設計時排版、命名、宣告、作用域、及一些特殊符號的規則和建議。
本規範適用於使用JavaScript語言程式設計的產品和專案。
2 術語和定義
規則:程式設計時強制必須遵守的原則。
建議:程式設計時必須加以考慮的原則。
格式:對此規範格式的的說明。
說明:對此規範或建議進行必要的解釋。
例項/如:對此規範或建議從正、反兩個方面給出的例子。
1命名規範
1.1基本規則
規範的命名能使程式更易閱讀,從而更易於理解。它們也可以提供一些標識功能方面的資訊,有助於更好的理解程式碼和應用。
1) 規則一:使用可以準確說明變數、函式、原型(prototype)的完整英文描述符。嚴禁使用漢語拼音、不相關單詞及漢字進行命名,例項:firstName,listAllUsers或 CorporateCustomer等;
2) 規則二:儘量少用縮寫,但如果一定要使用或名稱過長(不超過 25 個字母),當使用公共縮寫和習慣縮寫等,如實現(implement)可縮寫成impl,經理(manager)可縮寫成mgr等,嚴禁濫用縮寫;
3) 規則三:變數命名必須以小寫字母開頭,命名使用駱峰命名規則;
4) 規則四:方法名必須使用動詞或動詞短語命名,例項:getIdcName()、export()等;
5) 規則五:避免使用相似或者僅在大小寫上有區別的名字,以免不嚴格區分大小寫的系統視為同一名稱;
6) 規則六:避免命名中含有數字,但可以用2表示to,4表示for,另末尾使用數字表示同一系列的除外,如var$td_1 = $(‘.grid td’)[1];
7) 規則七:類名、建構函式、公共物件例項等名稱首字母大寫。
var MyCommon = { getSmallClassFromBigClass: function() {} } |
1.2相關建議
以下為相關建議,非必要遵循,但需要考慮
1) 建議一:變數如果設定為私有變數,函式為私有函式,則前面新增下劃線進行標註;公有變數和函式不新增下劃線
例項一: var MyClass = function() { var _thisTotal = 0; var _doSomething = function() {}; this.getThisTotal = function() { return _thisTotal; }; }; var myClassInstance = new MyClass(); myClassInstance.total = myClassInstance. getThisTotal(); |
例項二: function MyClass() { this._thisTotal = 0; this._doSomething = function() {}; } MyClass.prototype.getThisTotal = function() { return this._thisTotal; }; var myClassInstance = new MyClass(); myClassInstance.total = myClassInstance.getThisTotal(); |
2) 建議二:前面加"is" 的變數名應該為布林值,同理 "has","can" 或者 "should"亦如此;
3) 建議三:重複變數建議使用"i", "j", "k" (依次類推)等名稱的變數;
4) 建議四:全域性變數、常量應該全部大寫;
5) 建議五:術語"initialize" 或者 "init" 作為變數名應為已經例項化(初始化)完成的類或者其他型別的變數;為函式,應為初始化操作。
2程式碼組織規範
基本原則:利於個人開發,便於相互交流。
【說明】:因個人習慣和編輯器等可以設定而形成自己獨特的風格,但必須前後一致,並符合本規範的基本規則、建議和格式。
2.1縮排
原則:
(1)程式碼中以TAB(4個字元)縮排,在編輯器中請將TAB設定為相同的長度,否則在不同編輯器或設定下會導致TAB長度不等而影響整個程式程式碼的格式;
(2)同一程式碼塊中的程式碼對齊,這裡所說的程式碼塊,包括但不限於:function、if else語句、while、for等,即使用{}包圍的程式碼。
2.1註釋
原則:不吝惜程式碼註釋,重要函式、變數必須添加註釋;特殊函式、變數、常量必須添加註釋。
註釋的格式,可參考如下所示:
1)變數註釋:
// 初始化序列號 var index = 0; |
var index = 0; // 初始化序列號 |
2)函式註釋,包括a.函式描述及其功能說明;b.引數描述應包括型別、引數名、引數描述;有返回值的需要對返回值進行相應描述:
/** * 繫結事件 * @param {Object} $detailDom 當前變更詳情頁面主體DOM物件 * @return null */ function _bindEvent($detailDom) { |
/** * 檢視專線詳情 * @param {jQueryObject} $grid 列表DOM容器 * @param {String} selector 需要新增詳情連結的選擇器 * @param {Boolean} needSpecialId 是否需要指定其他特定id,預設不傳,即false * @param {String} specialIdName needSpecialId為true,此值必傳,即指定id的屬性名稱 * @return {Boolean} result 操作是否成功 */ viewDetail: function($grid, selector, needSpecialId, specialIdName) { var self = this; |
3)檔案註釋,應該包含檔案描述、功能簡介和作者,還可以加上建立時間:
/** * 本js實現專線續費申請頁面所有功能 * @author xuweijian * @date 2015/10/12 15:25:33 */ $(function() { |
4)行註釋與塊註釋:使用 //…的註釋方法來註釋需要表明的內容;使用/**和*/註釋的方法來註釋需要表明的內容。
3 編碼規範
3.1 變數編碼規範
原則:在遵循命名規則之上,應遵守以下規則,
(1)申明多個變數,變數之間使用逗號分隔;同時建議逗號與變數之間新增一個空格,避免過於擁擠,或是換行申明(此時可以對某個變數添加註釋!),
例項一: var name = ‘’, value = ‘’, title = ‘’; |
例項二: var name = ‘’, value = ‘’, // 註釋 title = ‘’; |
(2)變數申明時,應明確變數的型別,可以立即賦值,儘量避免變數的型別在使用過程中被轉換;
(3)儘量避免魔數(Magicnumbers),他們應該使用常量來代替;
(4)宣告變數必須加上 var 關鍵字,否則將成為全域性變數(Document或者 Window),進而成為汙染全域性的變數;
3.2 函式編碼規範
原則:
(1) 所有的函式在使用前進行宣告,內函式的宣告跟在var 語句的後面;
(2) 不要在語句塊(if…else等)內宣告一個函式;
其編碼風格應該遵循這幾點建議:
1) 建議一:函式名與引數()之間不要留有空格;
2) 建議二:引數列表之間使用逗號分隔,逗號與引數之間留有一個空格;
3) 建議三:使用右側簡約模式,)與{之間留一個空格;
4) 建議四:避免參數過多現象,一般不超5個,過多使用物件傳入;
5) 建議五:匿名函式不應該換行,如:$(‘#id’).bind(function(){…});中引數為匿名函式不應該換行處理,函式的主體遵循前面建議與原則;
function outer(c,d) { var e = c * d; function inner(a, b) { return (e * a) + b; } return inner(0, 1); } |
// 簡約模式 function outer(c,d) { var e = c * d; function inner(a, b) { return (e * a) + b; } return inner(0, 1); } |
在函式體中,我們應遵循以下建議:
1)建議一:避擴音供多個出口;
//不要使用這種方式,當處理程式段很長時將很難找到出口點 if (condition) { return A; } else { return B; } |
//建議使用如下方式 var result = null; if (condition) { result = A; } else { result = B; } return result; |
2)建議二:函式體中程式碼不應過長,一般不要超過100行;
原則:表示式和語句應清晰、簡潔,易於閱讀和理解,避免使用晦澀難懂的語句。使用圓括號明確表示式執行優先順序。
3.3.1控制語句
1)建議一:判斷中如有常量,則應將常量置與判斷式的右側。如:
if ( true == isAdmin())... if ( null == user)... |
2)建議二:boolean型別判斷語句儘量明確條件比較值true/false
//不建議使用 if (isCond)... if (!isCond)... |
//儘量使用 if (true == isCond)… if (false == isCond)… if (true != isCond)… |
編碼風格應遵循以下建議:
(1) 建議一:if…else if…else語句必須使用{}將每個判斷條件後的執行語句括起來。
(2) 建議二:if…else if…else與小括號、大括號之間應該空一格;
(3) 建議三:條件中的變數與“==”、“===”之間應該空一格;
(4) 建議四:型別確定的變數,在比較時,應使用嚴格相等符“===”,即”0” ===0比較值是false。
3.3.2迴圈語句
原則:
(1) 迴圈中必須有終止迴圈的條件或語句,避免死迴圈。
(2) 當多層迴圈巢狀時,計數器變數注意不要有衝突。
(3) 注意迴圈條件在執行迴圈過程中是否會發生變化,如果會則必須把迴圈條件的值在執行迴圈前獲取而不要在每次迴圈去執行。
(4) 考慮執行效率問題也應把迴圈條件值放在迴圈執行前獲取。
建議:
(1) 使用最基本的for迴圈,儘量避免使用for …in迴圈;
(2) for …in迴圈可用於用於object/map/hash 的遍歷,對 Array 用 for-in 迴圈有時會出錯,不建議使用;
(3) for迴圈中條件語句,不應該每次執行一個操作(如計算),應該在初始語句中實現;
// 不建議每次查詢length的值 for (var i = 0; i < data.length; i++) { } |
// 建議在初始語句中賦值一個變數 for (var i = 0, len = data.length; i < len; i++) { } |
3.3.3語句規範
原則:
(1) 除了語句塊最後一條語句可以沒有分號“;”以外,每條語句必須以分號結束,以避免程式碼壓縮後造成解析失敗。
(2) 當代碼塊中只有一條語句,也不應該省略大括號,如
if (null == $tab) { return ; // 雖然只有一條語句,也不應該省略{} } |
3.3.4運算子規範
原則:
(1) 賦值符號、比較符號兩側的變數應該在同一行,不要進行換行;
(2) 字串使用單引號(’)要優於雙引號(”),尤其是在建立一個包含 HTML 程式碼的字串時;
3.4類、物件與原型鏈規範
原則:
(1) 使用 Array 和 Object 字面量語法, 而不使用 Array 和 Object 構造器(newArray()),避免因傳參不合適導致錯誤;
(2) 其命名規範參考第1節中命名規範;
編碼風格,建議如下:
1)比較長的識別符號或者數值, 不要為了讓程式碼好看些而手工對齊. 如:
CORRECT_Object.prototype = { a: 0, b: 1, lengthyName: 2 }; |
不要這樣做: WRONG_Object.prototype = { a : 0, b : 1, lengthyName: 2 }; |
2)屬性名與屬性值之間不應該擁擠,應該在冒號“:”與屬性值之間空一格;
3.5錯誤處理
基本原則:
(1) 通常的法則是系統在正常狀態並且使用者正常操作下,不應產生任何異常。
(2) 對可預見的錯誤不進行捕捉。
(3) 對不可預見或者難以解決錯誤進行try{…}catch(e){..}捕捉處理。
3.5.1可預見錯誤
對可預見的錯誤不進行捕捉處理,而是在錯誤發生前通過條件判斷避免發生,如:
//若不對div1是否為null進行檢查,則在其為null時會丟擲缺少物件錯誤 document.getElementById(“div1”).style.width = 100; |
//預先對物件進行檢查 var objDiv1 = document.getElementById(“div1”); if(objDiv1!=null){ objDiv1.style.width = 100; } |
3.5.2不可預見錯誤
對不可預見或者因瀏覽器、指令碼解析器BUG造成的難以解決的錯誤需要進行捕捉處理,如:
try{ xmlhttp.open(“GET”,url,NOT_ASYNC); }catch(e){ console.log(e.description); } |
【說明】:對捕捉到的錯誤一般情況必須給出反饋處理,例如console.log(),除非有必要提醒使用者,否則不應該使用alert()。
以下規範,除了說明為建議、格式外,均為必須遵循的原則:
(1) eval是惡魔。eval 是JavaScript中最容易被濫用的方法,避免使用它。
(2) 不要給setTimeout或者setInterval 傳遞字串引數,應該使用函式引數。
(3) this僅在物件構造器, 方法, 閉包中使用。
this 的語義很特別。 有時它引用一個全域性物件(大多數情況下),呼叫者的作用域,DOM 樹中的節點(新增事件處理函式時), 新建立的物件(使用一個構造器),或者其他物件(如果函式被call()或apply())。使用時很容易出錯。
【說明】:在內嵌函式想要使用外層函式的呼叫者,必須將外層呼叫者賦值給一個變數,通常是self。
(4) 不要使用with(){}。
(5) 千萬不要修改內建物件, 如Object.prototype 和 Array.prototype 的原型;
(6) 使用 join() 來建立字串。
通常是這樣使用的,但這樣在 IE 下非常慢: function listHtml(items) { var html = '<div class="foo">'; for (var i = 0, len = items.length; i < len; ++i) { if (i > 0) { html += ', '; } html += itemHtml(items[i]); } html += '</div>'; return html; } |
可以用下面的方式: function listHtml(items) { var html = []; for (var i = 0, len = items.length; i < len; ++i) { html[i] = itemHtml(items[i]); } return '<div class="foo">' + html.join(', ') + '</div>'; } |
【說明】:即用陣列作為字串構造器, 然後通過join('') 轉換成字串。不過由於賦值操作快於陣列的 push(), 所以儘量使用賦值操作.
【參考文獻】