可讀性的大部分內容都是和程式碼縮排相關的,必須保證程式碼有良好的格式。可讀性的另一方面就是註釋,一般而言,有如下一些地方需要進行註釋
1.1.1 函式和方法
每個函式或方法都應該包含一個註釋,描述其目的和用於完成任務所可能使用的演算法,陳述事先的假設也非常重要,如引數代表什麼,函式是否有返回值等等
1.1.2 大段程式碼
用於完成單個任務的多行程式碼應該在前面放一個描述任務的註釋
1.1.3 複雜的演算法
如果使用了一個獨特的方式解決某個問題,則要在註釋中解釋你是如何做的,這不僅僅可以幫助其它瀏覽你程式碼的人,也能在下次你自己查閱程式碼的時候幫助理解
1.1.4 Hack
因為存在瀏覽器差異,JavaScript程式碼一般會包含一些Hack,不要假設其他人在看程式碼的時候能夠理解Hack所要應付的瀏覽器問題,如果因為某種瀏覽器無法使用普通的方法,所以你需要用一些不同的方法,那麼請將這些資訊放在註釋中。
1.1.5 程式碼排版
1.1.5.1 行長度
每行程式碼應小於 80 個字元。如果程式碼較長,應儘量選擇換行,下一行程式碼應縮排4 個空格。這樣可以使程式碼排版整齊,減輕閱讀程式碼的疲勞感,以增強程式碼的可閱讀性
1.1.5.2 行結束
JavaScript 語句應該以分號結束。但大多數瀏覽器允許不寫分號,只要在本應是分號的地方有一個換行符就行。但是如果程式碼行較長需要換行的時候,有哪些注意事項呢?換行應選擇在操作符和標點符號之後,最好是在逗號','之後,而不要在變數名、字串、數字、或')' ']' '++' '--'等符號之後換行。這樣可以有效的防止拷貝、貼上而引起的錯誤,並可有效地增強程式碼的可閱讀性。
例如:var valueB = valueA ///bad
+1;
可以替換為:var valueC = valueB + ///good
valueA;
1.1.5.3註釋
我們會強調程式碼中註釋數量的多少,而輕視了對註釋質量的提高。編碼是及時新增註釋,會給後續程式碼的維護人員帶來很大的便利。但是如果註釋不注意更新,或者由於拷貝、貼上引起的錯誤的註釋,則會誤導閱讀人員,反而給閱讀帶來障礙,除了註釋要及時更新外,我們還應對註釋的內容要特別關注。註釋要儘量簡單、清晰明瞭,避免使用含混晦澀的語言,同時著重註釋的意義,對不太直觀的部分進行註解。
例如:
//following section is used to initialize golbal variables (good)
var valueA = 0; //initialize valueA to be sero (bad)
var valueB = 1;
...
//call f1 function after waiting for 50 seconds. (good)
setTimeout (f1,50000); //set timeout to be 20s (copy error)
大功能塊的功能描述:
/*
*@desc:功能描述
*@param:引數描述
*@return:返回值
*/
1.1.5.4縮排
建議使用4個空格來進行縮排
1.1.5.5空白符
適當的空白行可以大大提高程式碼的可閱讀性,可以使程式碼邏輯更清晰易懂。同時,在表示式中適當的留空白,也會給程式碼的閱讀帶來方便,關鍵字的後面如有括號,則最好在關鍵字和左括號'('之間留空白,如 for, if, while 等。而函式名和括號之間則不宜留空白,但若是匿名函式,則必須在function 和左括號'('之間留空白,否則,編輯器會誤認為函式名為function。在表示式中,二元運算子( 除左括號'(',左方括號'[',作用域點'.')和兩個運算元之間最好留空白。一元運算子(若不是詞typeof 等)和其運算元之間不宜留空白。逗號','的後面需要留空白,以顯示明確的引數間隔,變數間隔等。分號';'之後通常表明表達語句的結束,而應空行。在for 的條件語句中,分號之後則應該留空白。
總結一句就是縮排和註釋可以帶來更可讀的程式碼,還有就是用空行來將邏輯相關的程式碼塊分割開可以提高程式的可讀性,增加程式的可讀性只為了在未來程式碼更容易維護。
1.2變數和函式命名
JavaScript是嚴格區分大小寫的,名稱的也遵循以下規則:
- 第一個字元必須是字母、下劃線、或一個美元符號$
- 其它字元可以是字母、下劃線、美元符號或數字
- 變數、引數、成員變數、函式等名稱均以小寫字母開頭,構造器的名稱以大寫字母開頭
- 下劃線'_'開頭的變數一般習慣於標識私有/區域性成員
- 美元符號'$'開頭的變數習慣於標識系統相關,比如系統程式等。應避免用下劃線'_'或美元符號'$'來命名識別符號。儘可能地降低程式碼的閱讀負擔
每一行最多隻包含一條語句,必須將分號放在簡單語句的結尾外,雖然分號在JavaScript是可有可無了,但是為了壓縮後不容易報錯,強制性的必須每條js程式碼都得以分號結束
1.2.1 變數名應為名詞
如car或person,如果是私有變數,則在名稱前加_下劃線
1.2.2 函式名應該為動詞開始
如getName(),返回布林型別值的函式一般以is開始,如isEnable(),如果是普通函式,則第一個字母小寫,如果是建構函式,則第一個字母大寫。函式名與((左括號)之間不應該有空格。)(右括號)與 開始程式體的{(左大括號)之間應插入一個空格,}(右大括號)應該與函式名在同一行而不應該另起一行
1.2.3 變數和函式都應使用合乎邏輯的名字
不要擔心長度,長度問題可以通過處理和壓縮
1.2.4 所有變數宣告都需要放到函式最頂部宣告或者說是作用域開始部位宣告
1.3 變數型別透明
因為JavaScript是弱型別(也叫鬆散型別)語言,很容易忘記變數所應包含的資料型別。使用匈牙利標記法來指定變數型別,匈牙利標記法就是在變數名之前加上一個或多個字元來表示資料型別。JavaScript中最傳統的匈牙利標記法是用單個字元表示基本型別:“O”程式碼物件,“S”代表字串,“I”代表整數,“F”代表浮點數,“B”代表布林型。如下所示
var bFound; //布林型
var iCount; //整數
var sName; //字串
var oPerson; //物件
javascript變數宣告的一點感想
相對於C/C++來說,ECMAScript裡的for迴圈並不能建立一個區域性的上下文。
for (var k in {a: 1, b: 2}) {
alert(k);
}
alert(k); // 儘管迴圈已經結束但變數k依然在當前作用域
任何時候,變數只能通過使用var關鍵字才能宣告。
上面的賦值語句:
a = 10;
這僅僅是給全域性物件建立了一個新屬性(但它不是變數)。“不是變數”並不是說它不能被改變,而是指它不符合ECMAScript規範中的變數概念,所以它“不是變數”(它之所以能成為全域性物件的屬性,完全是因為javascript中存在一個global物件,這樣的操作不是宣告一個變數而是給global物件增加一個a屬性。
下面看一個簡單的例題來說明問題
if (!("a" in window)) {
var a = 1;
}
alert(a);
首先,所有的全域性變數都是window的屬性,語句 var a = 1;等價於window.a = 1;
你可以用如下方式來檢測全域性變數是否宣告
"變數名稱" in window
第二,所有的變數宣告都在範圍作用域的頂部,看一下相似的例子:
alert("a" in window);
var a;
此時,儘管宣告是在alert之後,alert彈出的依然是true,這是因為JavaScript引擎首先會掃墓所有的變數宣告,然後將這些變數宣告移動到頂部,最終的程式碼效果是這樣的:
var a;
alert("a" in window);
第三,你需要理解該題目的意思是,變數宣告被提前了,但變數賦值沒有,因為這行程式碼包括了變數宣告和變數賦值。
你可以將語句拆分為如下程式碼:
var a; //宣告 a = 1; //初始化賦值
所以總結起來就是當變數宣告和賦值在一起用的時候,JavaScript引擎會自動將它分為兩部以便將變數宣告提前,不將賦值的步驟提前是因為他有可能影響程式碼執行出不可預期的結果。
題目中的程式碼相當於:
var a;
if (!("a" in window)) {
a = 1;
}
alert(a);
根據上述例題的分析,宣告變數時如果是宣告的區域性變數前面一定要加var,如果宣告的是全域性變數可以不加var(最好限制全域性變數的個數,儘量使用區域性變數)
下面講述一個使用var的幾個特性
使用var語句多次宣告一個變數不僅是合法的,而且也不會造成任何錯誤。
如果重複使用的一個宣告有一個初始值,那麼它擔當的不過是一個賦值語句的角色。
如果重複使用的一個宣告沒有一個初始值,那麼它不會對原來存在的變數有任何的影響。
沒有var宣告的變數,是作為全域性變數存在的;有var宣告的變數,屬於區域性變數,尤其是在函式內部。並且,經過測試,帶var宣告比不帶var速度要快。函式內儘量多設區域性變數,這樣即安全又快速,變數操作也更加合理,不會因為函式內胡亂操作全域性變數而導致邏輯錯誤。
宣告物件時最好使用物件自面量的方式,這樣的速度相對new的方式要快很多。
變數名是自己取的,為了照顧語義和規範,變數名可能稍長,但是注意了,變數名的長度也會影響程式碼的執行速度。長的變數名宣告的執行速度沒有短的快。