Javascript代碼及註釋規範
javascript
爲規範前端開發代碼,提升代碼質量,特制定此文檔,其中聲明,安全和分號這三節是必須執行的,組件類必須遵循註釋規範。css
變量聲明必須加var關鍵字,嚴格控制做用域;html
建議使用駝峯式命名變量和函數,如:functionNamesLikeThis, variableNamesLikeThis, ClassNamesLikeThis,namespaceNamesLikeThis;前端
私有成員變量和方法命名如下劃線開頭,如:var _this;java
常量定義單詞所有大寫,如下劃線鏈接,但不要用const關鍵字來聲明,如:SOME_CONSTANTS;jquery
函數參數大於3個時,應以對象形式做爲參數集傳遞;git
禁止在代碼塊中聲明函數,錯誤的範例:if (true) {function foo() {}};es6
禁止用new來實例化基本類型,錯誤的範例:var x = new Boolean(false);github
直接定義數組或對象,而不使用new關鍵字聲明,錯誤的範例:var a = new Array();var o = new Object();算法
使用單引號來定義字符串;
文件名必須所有用小寫,文件名分隔符用中劃線鏈接,版本鏈接符用實心點,合併文件的文件名鏈接符用下劃線,如:passport-core.min.js和reset-1.0_utils-1.0.css;
審查用戶輸入,如:從URL獲取參數,使用跳轉頁面的referer,用於eval或DOM操做的用戶數據;
禁止經過在iframe使用script進行跨域回調;
警戒jquery xss,禁止這樣的寫法:$(window.location.hash);
禁止引用站外資源;
函數表達式(有別於函數聲明,如:function x(){})必須用分號結束,下面是錯誤的範例,第三行漏掉分號,後面的函數被看成參數傳遞給myMethod,致使解析錯誤:
var myMethod = function() { return 42; } (function() { // 一個匿名函數,在這裏會被錯誤解析看成參數調用致使報錯 })();
因爲沒法完美的控制都不出現異常,因此儘可能在可能但不肯定出現異常的地方(大量運算,AJAX請求,數組操做或DOM操做等)用try-catch(e)來拋出異常,這樣有利於規模較大的項目中排查錯誤。使用自定義異常拋出錯誤信息,更有利於錯誤信息閱讀,且更加通用,由於不一樣瀏覽器拋出的信息不同,有時候可能很難定位到問題所在位置,特別是IE下可能遇到的以下報錯信息:
Stack overflow at line: 0 或: 未知的運行時錯誤
爲獲取最大化的可移植性和兼容性,代碼中應使用標準中支持的方式來書寫代碼,雖然瀏覽器支持某些語法但不在規範中,你沒法保證你未來不會遇到兼容其餘瀏覽器的狀況,若是這個瀏覽器徹底或部分特性只按規範實現。
//錯誤的範例 var char = 'hello world'[3]; var myForm = document.myForm; //正確的寫法 var char = 'hello world'.charAt(3) var myForm = document.forms[0];或者var myForm = document.getElementsByTagName('form')[0];
類中的成員變量使用構造函數來初始化;
除非是必須移除類的成員,不然析構函數中對成員的銷燬應經過將其設置爲null,而不是用delete,由於從新賦值方式性能比用delete好;
避免經過prototype方式污染內置對象原型鏈;
不使用with關鍵字,容易形成做用域混亂;
this僅用於類成員函數或對象中;
通用全局函數,特別是通用組件代碼應將業務邏輯放入閉包中,並經過「命名空間」將其引入;
若函數中使用到全局變量,則訪問全局變量時應使用window來引入,如:
var somevar = 10; function getvar(){ var num = window.somevar + 1; //... return num; }
儘可能使用優雅的模版寫法,避免多行字符串用\加換行的方式或使用+運算鏈接字符串這種難維護的編碼方式;
禁止使用IE條件編譯@cc_on;
沒有強制要求代碼需格式化成什麼樣子,但儘可能使代碼具備較高的可讀性。下面給出一些建議的代碼風格:
// 花括號起始位置與語句開始在同一行 if (something) { // ... } else { // ... } // 數組和對象書寫 var arr = [1, 2, 3]; // [以後,]以前沒有空格 var obj = {a: 1, b: 2, c: 3}; // {以後,}以前沒有空格 // 多行數組和對象書寫 var a = [ 'huangrongrong', 'chenying', 'small grey grey', 'shenshunlin' ]; var pos = { top: 10, right: 20, bottom: 15, left: 12 }; // 將業務邏輯相關的代碼寫一塊兒,不相關的以空行分隔 doSomethingTo(x); doSomethingElseTo(x); andThen(x); nowDoSomethingWith(y); andNowWith(z); var x = a ? b : c; // 一行能寫完 // 寫不完能夠換行加縮進 var y = a ? longButSimpleOperandB : longButSimpleOperandC; // 或者這樣 var z = a ? moreComplicatedB : moreComplicatedC;
對於代碼中須要進行==邏輯判斷的變量,建議進行強制類型轉換或使用===代替。
下列值在布爾表達式中結果爲false:
null
undefined
'' //空字符串
0 //數字
而下面的爲true:
'0' //字符串
[] //空數組
{} //空對象
還有一些難以區分的表達式,如下表達式結果全爲true:
Boolean('0') == true '0' != true 0 != null 0 == [] 0 == false Boolean(null) == false null != true null != false Boolean(undefined) == false undefined != true undefined != false Boolean([]) == true [] != true [] == false Boolean({}) == true {} != true {} != false
文檔註釋遵循YUIDoc規範(http://yui.github.io/yuidoc/syntax/),全部的文件、類、方法和屬性都應該用合適的標記和類型進行註釋。
YUIDoc要求文檔中至少要有一個class和constructor標記來定義類和構造函數;
YUIDoc中註釋塊必須以/**(至少兩個星號)開頭;
方法、參數和返回值等必須有註釋說明;
單行註釋使用//;
對於代碼中特殊用途的變量、存在臨界值、函數中使用的hack、使用了某種算法或思路等須要進行註釋描述;
建議加入開發者我的信息及最後修改時間註釋,雖然這些信息不會被YUIDoc解析顯示;
下面給出代碼註釋實例做爲參考,更多標記和類型定義請參考YUIDoc官方文檔。
/** 這是一個UELib類 @class UELib @constructor @author hiwanz <princeb4d@gmail.com> @modified someone @date 2013-06-25 **/ function UELib = function(){}; /** My method description. Like other pieces of your comment blocks, this can span multiple lines. @method css @param prop {String} set/get a css property @param [value] {String} A value you want to set to a css property @example ele.css('width', '100%'); @return {Boolean} Returns true on success **/ UELib.prototype.css = function(prop,value){ };
待定
目前規範還沒法徹底自動化審查,團隊根據實際狀況,在不與規範衝突的前提下,使用JSHint進行審查,配置文件以下:
{ "jquery": true,//檢查預約義的全局變量,防止出現$未定義,該項根據實際代碼修改 "bitwise": false,//不檢查位運算 "browser": true,//經過瀏覽器內置的全局變量檢測 "devel":true,//容許對調試用的alert和console.log的調用 "camelcase": false,//不強制驗證駝峯式命名 "curly": true,//強制使用花括號 "eqeqeq": false,//不強制使用===比較運算符 "es3":true,//兼容es3規範,針對舊版瀏覽器編寫的代碼 "esnext": false, //不使用最新的es6規範 "expr": true,//容許未賦值的函數名錶達式,例如console && console.log(1) "forin":false,//不強制過濾遍歷對象繼承的屬性 "freeze":false,//不限制對內置對象的擴展 "immed": true,//禁止未用括號包含當即執行函數 "indent": false,//不強制縮進 "latedef": true,//禁止先調用後定義 "maxdepth":false,//不限制代碼塊嵌套層數 "maxparams":false,//不限制函數參數個數 "newcap": false,//不對首字母大寫的函數強制使用new "noarg": false,//不由止對arguments.caller和arguments.callee的調用 "noempty":false,//不由止空代碼塊 "nonew":false,//容許直接new實例化而不賦值給變量 "plusplus":false,//容許++和--運算符使用 "quotmark": "single",//字符串使用單引號 "scripturl": true,//容許javascript僞協議的url "smarttabs": true,//容許混合tab和空格縮進 "strict": false,//不強制使用es5嚴格模式 "sub": true,//容許用[]形式訪問對象屬性 "undef": true,//禁止明確未定義的變量調用,若是你的變量(myvar)是在其餘文件中定義的,可使用/*global myvar */繞過檢測 "unused": false,//容許定義沒用的變量,在某些函數回調中,常常出現多個參數,但不必定會用 "multistr": false,//禁止多行字符串,改用加號鏈接 "globals": { "jQuery": true } }