上次淺談了下關於CSS的編碼規范,大部分童鞋持贊同意見,仍存在一些童鞋不太理解這些規范的意義。
如果是個人或者小作坊開發,其實這些所謂的編碼規范也沒啥意思,因為大家寫好的代碼直接就給扔到網上去了,很少有打包、壓縮、校檢等過程,別人來修改你代碼的情況也比較少。但是,對於一定規模的團隊來說,這些東西還是挺有必要的!一個是保持代碼的整潔美觀,同時良好的代碼編寫格式和注釋方式可以讓后來者很快地了解你代碼的大概思路,提高開發效率。
那么這次,繼續拋磚引玉,說說Javascript一些需要引起注意的地方(這些東西也是團隊開發的時候大家集思廣益總結出來的)。
不規范寫法舉例
1. 句尾沒有分號
var isHotel = json.type == "hotel" ? true : false
2. 變量命名各種各樣
var is_hotel; var isHotel; var ishotel;
3. if 縮寫
if (isHotel) console.log(true) else console.log(false)
4. 使用 eval
var json = eval(jsonText);
5. 變量未定義到處都是
function() { var isHotel = 'true'; ....... var html = isHotel ? '<p>hotel</p>' : ""; }
6. 超長函數
function() { var isHotel = 'true'; //....... 此處省略500行 return false; }
7. ..........
書寫不規范的代碼讓我們難以維護,有時候也讓我們頭疼。
(禁止)、(必須)等字眼,在這里只是表示強調,未嚴格要求。
前端規范之JavaScript
1. tab鍵用(必須)用四個空格代替
這個原因已經在前端編碼規范之CSS說過了,不再贅述。
2. 每句代碼后(必須)加";"
這個是要引起注意的,比如:
a = b // 賦值 (function(){ //.... })() // 自執行函數
未加分號,結果被解析成
a = b(function(){//...})() //將b()()返回的結果賦值給a
這是截然不同的兩個結果,所以對於這個問題必須引起重視!!!
3. 變量、常量、類的命名按(必須)以下規則執行:
1) 變量:必須
采用駱駝峰
的命名且首字母小寫
// 正確的命名 var isHotel, isHotelBeijing, isHotelBeijingHandian; // 不推薦的命名 var is_Hotel, ishotelbeijing, IsHotelBeiJing;
2) 常量:必須
采用全大寫的命名,且單詞以_
分割,常量通常用於ajax請求url,和一些不會改變的數據
// 正確的命名 var HOTEL_GET_URL = 'http://map.baidu.com/detail', PLACE_TYPE = 'hotel';
3) 類:必須
采用駱駝峰
的命名且首字母大寫,如:
// 正確的寫法 var FooAndToo = function(name) { this.name = name; }
4. 空格的使用
1)if
中的空格,先上例子
//正確的寫法 if (isOk) { console.log("ok"); } //不推薦的寫法 if(isOk){ console.log("ok"); }
()
中的判斷條件前后都(必須)
加空格()
里的判斷前后(禁止)
加空格,如:正確的寫法:if (isOk)
;不推薦的寫法:if ( isOk )
2)switch
中的空格, 先上例子
//正確的寫法 switch(name) { case "hotel": console.log(name); break; case "moive": console.log(name); break; default: // code } //不推薦的寫法 switch (name) { // switch 后不應該有空格, 正確的寫法: switch(name) { // code case "hotel": console.log(name); break; // break; 應該和console.log對齊 case "movie": // 每個case之前需要有換行 console.log(name); break; // break; 應該和console.log對齊 default: // code }
3)for
中的空格,先上例子
// 正確的寫法 var names = ["hotel", "movie"], i, len; for (i=0, len=names.length; i < len; i++) { // code } // 不推薦的寫法 var names = ["hotel", "movie"], i, len; for(i = 0, len = names.length;i < len;i++) { // for后應該有空格,每個`;`號后需要有空格,變量的賦值不應該有空格 // code }
for
后(必須)
加空格- 每個
;
后(必須)
加空格 ()
中禁止
用var
聲明變量; 且變量的賦值=
前后(禁止)
加空格
4)function
中的空格, 先上例子
// 正確的寫法 function call(name) { } var cell = function () { }; // 不推薦的寫法 var call = function(name){ // code }
- 參數的反括號后(
必須)
加空格 function
后(必須)
加空格
5)var
中空格及定義,先上例子
// 一個推薦的var寫法組 function(res) { var code = 1 + 1, json = JSON.parse(res), type, html; // code }
- 聲明變量
=
前后(必須)
添加空格 - 每個變量的賦值聲明以
,
結束后(必須)
換行進行下一個變量賦值聲明 (推薦)
將所有不需要進行賦值的變量聲明放置最后一行,且變量之間不需要換行(推薦)
當一組變量聲明完成后,空一行后編寫其余代碼
5. 在同一個函數內部,局部變量的聲明必須
置於頂端
因為即使放到中間,js解析器也會提升至頂部(hosting)
// 正確的書寫 var clear = function(el) { var id = el.id, name = el.getAttribute("data-name"); ......... return true; } // 不推薦的書寫 var clear = function(el) { var id = el.id; ...... var name = el.getAttribute("data-name"); ......... return true; }
推薦閱讀:JavaScript-Scoping-and-Hoisting
6. 塊內函數必須
用局部變量聲明
// 錯誤的寫法 var call = function(name) { if (name == "hotel") { function foo() { console.log("hotel foo"); } } foo && foo(); } // 推薦的寫法 var call = function(name) { var foo; if (name == "hotel") { foo = function() { console.log("hotel foo"); } } foo && foo(); }
引起的bug:第一種寫法foo
的聲明被提前了; 調用call
時:第一種寫法會調用foo
函數,第二種寫法不會調用foo
函數
注:不同瀏覽器解析不同,具體請移步湯姆大叔深入解析Javascript函數篇
7. (禁止)
使用eval,采取$.parseJSON
三個原因:
- 有注入風險,尤其是ajax返回數據
- 不方便debug
- 效率低,eval是一個執行效率很低的函數
建議:
使用new Function來代替eval的使用,最好就別用。
8. 除了三目運算,if
,else
等(禁止)
簡寫
// 正確的書寫 if (true) { alert(name); } console.log(name); // 不推薦的書寫 if (true) alert(name); console.log(name); // 不推薦的書寫 if (true) alert(name); console.log(name)
9. (推薦)
在需要以{}
閉合的代碼段前增加換行,如:for
if
// 沒有換行,小的代碼段無法區分 if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { if (merge && type == 'object') { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } } } // 有了換行,邏輯清楚多了 if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { // 處理merge邏輯 if (merge && type == 'object') { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } } }
換行可以是空行,也可以是注釋
10. (推薦)
使用Function
進行類的定義,(不推薦)
繼承,如需繼承采用成熟的類庫實現繼承
// 類的實現 function Person(name) { this.name = name; } Person.prototype.sayName = function() { alert(this.name); }; var me = new Person("Nicholas"); // 將this放到局部變量self function Persion(name, sex) { var self = this; self.name = name; self.sex = sex; }
平時咱們寫代碼,基本都是小程序,真心用不上什么繼承,而且繼承並不是JS的擅長的語言特性,盡量少用。如果非要使用的話,注意一點:
function A(){ //... } function B(){ //... } B.prototype = new A(); B.prototype.constructor = B; //原則上,記得把這句話加上
繼承從原則上來講,別改變他的構造函數,否則這個繼承就顯得很別扭了~
11. (推薦)
使用局部變量緩存反復查找的對象(包括但不限於全局變量、dom查詢結果、作用域鏈較深的對象)
// 緩存對象 var getComment = function() { var dom = $("#common-container"), // 緩存dom appendTo = $.appendTo, // 緩存全局變量 data = this.json.data; // 緩存作用域鏈較深的對象 }
12. 當需要緩存this
時必須使用self
變量進行緩存
// 緩存this function Row(name) { var self = this; self.name = name; $(".row").click(function() { self.getName(); }); }
self是一個保留字,不過用它也沒關系。在這里,看個人愛好吧,可以用_this, that, me等這些詞,都行,但是團隊開發的時候統一下比較好。
13. (不推薦)
超長函數, 當函數超過100行,就要想想是否能將函數拆為兩個或多個函數
14. 等你來填坑~
小結
規范是死的,羅列這些東西,目的是為了讓程序猿們對這些東西引起注意,平時寫代碼的時候注意格式,不僅僅方便了自己,也讓其他閱讀者看得舒服。
可能還有一些點沒有涉及到,如果你有好的建議,請提出來,我們一起打造一個良好的前端生態環境!
相關閱讀:前端編碼規范之CSS