淺談 JavaScript 程式設計語言的編碼規範

來源:互聯網
上載者:User
王丹丹 , IBM 中國系統與技術中心軟體工程師,自從 2006 年加入 IBM,一直從事 Web 系統設計和開發工作,有五年 PHP 應用程式設計開發經驗。

對於熟悉 C/C++ 或 Java 語言的工程師來說,JavaScript 顯得靈活,簡單易懂,對代碼的格式的要求也相對鬆散。很容易學習,並運用到自己的代碼中。也正因為這樣,JavaScript 的編碼規範也往往被輕視,開發過程中修修補補,最終也就演變成為後續維護人員的惡夢。軟體存在的長期價值直接與編碼的品質成比例。編碼規範能協助我們降低編程中不必要的麻煩。而 JavaScript 代碼是直接發送給客戶瀏覽器的,直接與客戶見面,編碼的品質更應該受到關注。

本文淺談 JavaScript 編程中關於編碼規範的問題,分析其中緣由。希望引起更多 Web 開發人員對 JavaScript 編碼規範問題的關注和對軟體產品品質問題的重視。

前言

提及 C/C++ 和 Java 編碼規範,相信許多工程師並不生疏。但說到 JavaScript 語言的編碼規範,也許您會忍俊不禁。JavaScript 不是文法很靈活嗎?變數隨時用隨時可以聲明;語句結束符可以不要;字串和數字也可以相加;參數多一個少一個也不會報錯。沒錯,當您從 C/C++ 和 Java 嚴格的文法規定之下,轉向 JavaScript 語言,會覺得自由了很多,輕鬆了很多。文法鬆散是 JavaScript 重要的特徵。它靈活易懂,給開發人員帶來了很多方便,但如果編寫過程中不注意,代碼的調試成本和維護成本則會無形地增加。

JavaScript 編碼會隨應被直接發送到用戶端的瀏覽器,代碼規範不只是代碼品質的保證,也影響到產品的長期信譽。希望 JavaScript 程式設計語言的規範問題也能同樣引起更多朋友的關注。

 




JavaScript 編碼規範建議

本文就 JavaScript 編碼過程中涉及的排版、命名、聲明、範圍、及一些特殊符號的使用等方面,根據個人在學習工作中的總結,給出自己的一些建議,並分析其中緣由,以供參考。

JavaScript 檔案引用

JavaScript 程式應該盡量放在 .js 的檔案中,需要調用的時候在 HTML 中以 <script
src="filename.js"> 的形式包含進來。JavaScript 代碼若不是該 HTML 檔案所專用的,則應盡量避免在 HTML
檔案中直接編寫 JavaScript 代碼。因為這樣會大大增加 HTML 檔案的大小,無益於代碼的壓縮和緩衝的使用。

另外,<script src="filename.js"> 標籤應盡量放在檔案的後面。這樣會降低因載入 JavaScript 代碼而影響頁面中其它組件的載入時間。

代碼排版

行長度

每行代碼應小於 80 個字元。

如果代碼較長,應盡量選擇換行,下一行代碼應縮排 8 個空格。這樣可以使代碼排版整齊,減輕閱讀代碼的疲勞感。換行縮排 8 個空格可以和程式碼片段的縮排 4 個空格區分開,以增強代碼的可閱讀性。

行結束

JavaScript
語句應該以分號結束。但大多數瀏覽器允許不寫分號,只要在本應是分號的地方有一個分行符號就行。但是如果程式碼較長需要換行的時候,有哪些注意事項呢?換行
應選擇在操作符和標點符號之後,最好是在逗號','之後,而不要在變數名、字串、數字、或')' ']' '++' '--'等符號之後換行。

這樣可以有效防止拷貝、粘貼而引起的錯誤,並可有效地增強代碼的可閱讀性。請見清單 1,代碼的輸出符合我們的期望。但就寫法而言,對
valueB 的指派陳述式是在變數 valueA 之後進行的換行,這很容易被誤解為 valueB=ValueA,給閱讀造成障礙。而對 valueC
的複製語句是在'+'之後進行的換行,就容易理解的多。這也是本文所提倡的換行方式。


清單 1. 行結束的位置

<mce:script language="javascript"><!--</p><p> var valueA = 1;<br /> var valueB = valueA ///bad<br /> +1;<br /> var valueC = valueB + ///good<br /> valueA;<br /> alert(valueB); //output: valueB=2<br /> alert(valueC);//output: valueC=3 </p><p>// --></mce:script>

縮排

關於縮排的問題,不只是 JavaScript,幾乎所有的語言編寫的時候,都會提及縮排的問題。縮排幾乎是代碼編寫規範的第一課,是代碼可閱讀性判斷的直接因素。

代碼縮排的好處是不言而喻的,但是對於如何縮排,則沒有標準而言。最受歡迎的是方便使用 TAB 鍵縮排,也有些喜歡用 2 個、4 個、8 個空格進行縮排。這樣縮排風格不一,也同樣給代碼的閱讀帶來障礙。

本文提倡用 4 個空格

來進行縮排,並在同一產品中採用同一種縮排標準。不支援用 TAB
鍵進行縮排。這是因為直到現在還沒有統一的標準來定義 TAB 鍵所代替的空白大小,有些編輯器解析為 4 個空格大小,有些則解析為 8
個。因而用不同的編輯器查看代碼,可能造成格式混亂。當然 TAB 簡單易用,為解決這個問題,建議在設定開發環境時,將編輯器裡的 TAB
快速鍵重新設定為 4 個空格。據瞭解 Eclipse, Vi, Nodepad++,Editplus, UltraEdit
等流行的編輯器,均提供了此功能。

注釋

代碼中的注釋很重要,自然也是毋庸置疑的。通常我們會強調代碼中注釋數量的多少,而輕視了對注釋品質的提高。編碼是及時添加註釋,會給後續
代碼的維護人員帶來很大的便利。但是如果注釋不注意更新,或者由於拷貝、粘貼引起的錯誤的注釋,則會誤導閱讀人員,反而給閱讀帶來障礙。

除了注釋要 及時更新

外,我們還應對注釋的內容要特別關注。注釋要盡量簡單、清晰明了,避免使用含混晦澀的語言,同時著重 注釋的意義

,對不太直觀的部分進行註解。請見清單 2。

 

清單 2. 有意義的注釋

 

<mce:script language="javascript"><!--</p><p> //following section is used to initialize golbal variables (good)<br /> var valueA = 0; //initialize valueA to be sero (bad)<br /> var valueB = 1;<br /> ...<br /> //call f1 function after waiting for 50 seconds. (good)<br /> setTimeout(f1,50000); //set timeout to be 20s (copy error)<br /> ... </p><p>// --></mce:script> 

這樣的注釋方式在 JavaScript 代碼中經常見到。"initialize valueA to be sero"
這樣的注釋有什麼用呢?難道閱讀程式的工程師從"var valueA = 0;"複製語句中看不出來嗎?"set timeout to be
20s"這條注釋,不只是因拷貝、粘貼引起的時間大小的錯誤,同時也誤導了程式員對這條語句的理解。setTimeout()
函數的作用並非是設定函數執行的逾時時間,而是等待一定時間後執行所調用的函數,害人匪淺呀。這樣的注釋內容寧可刪掉。

此外,JavaScript 的注釋有兩種"//" 和"/* .... */",建議"//"用作程式碼注釋,"/* .... */"形式用作對整個程式碼片段的登出,或較正式的聲明中,如函數參數、功能、檔案功能等的描述中。

標識符命名

JavaScript 中的標識符的命名規則:

  • 以字母、底線'_'或貨幣符號'$'開頭
  • 允許名稱中包含字母,數字,底線'_'和貨幣符號'$'
  • 區分大小寫

變數、參數、成員變數、函數等名稱均以小寫字母開頭,構造器的名稱以大寫字母開頭。底線'_'開頭的變數一般習慣於標識私人 /
局部成員。而貨幣符號'$'開頭的變數習慣於標識系統相關,比如系統進程等。應避免用底線'_'或貨幣符號'$'來命名標識符。儘可能地降低代碼的閱讀
負擔。

聲明

變數的聲明

儘管 JavaScript 語言並不要求在變數使用前先對變數進行聲明。但我們還是應該養成這個好習慣。這樣可以比較容易的檢測出那些未經聲明的變數,避免其變為隱藏的全域變數,造成隱患。

在函數的開始應先用 var
關鍵字聲明函數中要使用的局部變數,注釋變數的功能及代表的含義,且應以字母順序排序。每個變數單獨佔一行,以便添加註釋。這是因為
JavaScript 中只有函數的 {} 表明範圍,用 var 關鍵字聲明的局部變數只在函數內有效,而未經 var
聲明的變數則被視為全域變數。我們來看下清單 3。

 

清單 3. 局部變數聲明

<mce:script language="javascript"><!--</p><p> var valueA = "a";<br /> var valueB = "b";<br /> function f1() {<br /> var valueA = "c";<br /> alert("valueA="+valueA); //output: valueA=c<br /> valueB = "d";<br /> alert("valueB="+valueB); //output: valueB=d<br /> }<br /> f1();<br /> alert("valueA="+valueA); //output: valueA=a<br /> alert("valueB="+valueB); //output: valueB=d </p><p>// --></mce:script>

從上例的輸出驚奇地發現,用 var 聲明過的變數 valueA 和沒有聲明的變數 valueB 是有區別的。特別需要注意的是,在函數內部用 var 聲明的變數為局部變數,這樣可以有效地避免因局部變數和全域變數同名而產生的錯誤。

函數的聲明

函數也應在調用前進行聲明,內建函式應在 var 聲明內部變數的語句之後聲明,可以清晰地表明內部變數和內建函式的範圍。

此外,函數名緊接左括弧'('之間,而右括弧')'和後面的'{'之間要有個空格,以清楚地顯示函數名以其參數部分,和函數體的開始。若函
數為匿名 / 無名函數,則 function 關鍵字和左括弧'('之間要留空格,否則可能誤認為該函數的函數名為 function。

清單 4. 內建函式聲明

<mce:script language="javascript"><!--</p><p> var innerA = 1;<br /> function outF() {<br /> var innerA = 2;<br /> function _inF() {<br /> alert("valueA="+innerA);<br /> }<br /> _inF();<br /> }<br /> outF(); //output: valueA=2<br /> _inF(); //error: innerF is not defined </p><p>// --></mce:script>

從清單 4 的輸出可以看出,inF() 函數僅在 outF() 函數的內部生效,局部變數 innerA 對內建函式的範圍生效。這樣的編碼方式使得變數和函數的範圍變得清晰。

語句

對於簡單語句而言,需要提及的仍然是分號必要性,同時,一行最多有一個語句。如果一個指派陳述式是用函數和對象來賦值,可能需要跨多行,一定切記要在指派陳述式末加上分號。

這是因為 JavaScript 中,所有運算式都可以當語句,遇分行符號時會解析為運算式的結束,此時不規範的換行和分號的丟失,可能引入新的錯誤。

對於複合陳述式,if, for, while, do, switch, try … catch 等代碼體,函數定義的函數體,對象的定義等都需要放在花括弧'{}'裡面。

  • '{' 應在行末,標誌代碼塊的開始。
  • '}' 應在一行開頭,標誌代碼塊的結束,同時需要和'{'所在行的開始對齊,以表明一個完整的複合陳述式段。這樣可以極大地提高代碼的可閱讀性,控制邏輯能清晰地表現出來。
  • 被包含的程式碼片段應該再縮排 4 個空格。
  • 即使被包含的程式碼片段只有一句,也應該用花括弧'{}'包含。儘管不用花括弧代碼也不會錯,但如若需要增加語句的話,則較容易因花括弧遺漏而引起的編譯錯誤或邏輯錯誤。

return

語句在使用時也需謹慎,如果用運算式的執行作為傳回值,請把運算式和 return 放在同一行中,以免分行符號被誤解析為語句的結束而引起返回錯誤。return 關鍵字後若沒有返回運算式,則返回 undefined。構造器的預設傳回值為 this。

清單 5. return 運算式

<mce:script language="javascript"><!--</p><p> function F1() {<br /> var valueA = 1;<br /> var valueB = 2;<br /> return valueA + valueB;<br /> }<br /> function F2() {<br /> var valueA = 1;<br /> var valueB = 2;<br /> return<br /> valueA + valueB;<br /> }<br /> alert( F1() ); //output: 3<br /> alert( F2() ); //ouput: undefined </p><p>// --></mce:script>

在清單 5 中顯示了因返回運算式沒有和 return 關鍵字放在同一行而引起的返回錯誤,需重視。

特殊符號

空白符

適當的空白行可以大大提高代碼的可閱讀性,可以使代碼邏輯更清晰易懂。同時,在運算式中適當的留空白,也會給代碼的閱讀帶來方便。

關鍵字的後面如有括弧,則最好在關鍵字和左括弧'('之間留空白,如 for, if, while 等。而函數名和括弧之間則不宜留空白,但若是匿名函數,則必須在 function 和左括弧'('之間留空白,否則,編輯器會誤認為函數名為 function。

在運算式中,二元運算子 ( 除左括弧'(',左方括弧'[',範圍點'.') 和兩個運算元之間最好留空白。一元運算子(若不是詞 typeof 等)和其運算元之間不宜留空白。

逗號','的後面需要留空白,以顯示明確的參數間隔,變數間隔等。

分號';'之後通常表明表達語句的結束,而應空行。在 for 的條件陳述式中,分號之後則應該留空白。

{ } 和 [ ]

在 JavaScript 中,如需定義Null 物件和空數組,通常很自然地想到用 new Object() 和 new Array() 的方法。其實花括弧'{}'和方括弧'[]'可以直接用來定義一個Null 物件和一個空數組。這種書寫方法可以使代碼看起來簡單易懂。

== 和 ===

判斷"邏輯等"在代碼裡太平常的不過事情了,但 JavaScript
與其他熟知的程式設計語言不同的是,除了可以使用兩個等號'=='來作判斷以為,還可以使用三個等號'==='來進行邏輯等判斷。兩者的不同是'=='作邏輯
等判斷時,會先進行類型轉換後再進行比較。'==='則不會。因而,'=='進行的判斷結果可能產生偏差。'!='與'!=='的區別亦是如此。本文提倡
盡量使用'==='來進行邏輯等的判斷,用'!=='進行邏輯不等的判斷。

清單 6. === 的使用

<mce:script language="javascript"><!--</p><p> var valueA = "1";<br /> var valueB = 1;<br /> if ( valueA == valueB) {<br /> alert("Equal");<br /> }<br /> else {<br /> alert("Not equal")<br /> }<br /> //output: "Equal"<br /> if ( valueA === valueB) {<br /> alert("Equal");<br /> }<br /> else {<br /> alert("Not equal")<br /> }<br /> //output: "Not equal"</p><p>// --></mce:script>

清單 6 中,valueA 和 valueB 兩個變數的值顯然是不相等的,起碼 valueA 是個字串,而 valueB
是一個數字。但用'=='進行判斷是,程式卻輸出相等的字樣。這是因為編譯器對兩個變數進行比較時,因為他們的類型不同,而自動地將 valueB
轉換成字串,而後再和 valueA 進行比較的。用'==='得到的判斷結果正和預期的結果相符。

+

加號'+'也同樣是程式員所熟知的操作符之一。JavaScript 和其他程式設計語言不同的是,在 JavaScript
中,'+'除了表示數字值相加,字串相串連以外,還可以作一元運算子用,把字串轉換為數字。因而如果使用不當,則可能與自增符'++'混淆而引起計算
錯誤。這一點,在清單 7 中可以清楚地看出。


清單 7. 巧用 + 號

<mce:script language="javascript"><!--</p><p> var valueA = 20;<br /> var valueB = "10";<br /> alert( valueA + valueB); //ouput: 2010<br /> alert( valueA + (+valueB)); //output: 30<br /> alert( valueA + +valueB); //output:30<br /> alert( valueA ++valueB); //Compile error </p><p>// --></mce:script>

總結

本文就 JavaScript 代碼的排版、命名、聲明、語句、和一些特殊字元的使用等方面,談了自己對 JavaScript
編程規範的建議。此外,還有許多方面需要深入瞭解研究,如 with, eval 語句和 this
對象的使用等等。我們在認識其普遍性的同時也需要注意其特殊性,在編寫代碼時多用心留意,以創造更多更優質的程式碼。

 

聲明

本文所提及的 JavaScript 編程規範的建議是在學習和工作中歸納出來的,僅供技術交流使用。

 

參考資料

  • 《 JavaScript: The Definitive Guide 》第五版,http://oreilly.com/catalog/9780596101992

    ,由 David Flanagan 著,O'Reilly 出版,此書是 JavaScript 程式員必不可少的學習參考書;

  • 《 JavaScript 語言精粹》,http://www.china-pub.com/195292

    ,由雅虎資深 JavaScript 架構師 Douglas Crokford 著 , 電子工業大學出版,此書很好地講述了如何用 JavaScript 建立真正可擴充的和高效的代碼;

  • Douglas Crokford 的部落格,http://www.crockford.com

    ,提供了 Douglas 對 JavaScript 語言的研究課題,以及對一些經典問題的討論;

  • JavaScript 教程:http://www.w3school.com.cn/js/index.asp

    ,W3school 提供的 JavaScript 基礎教程。

  • developerWorks Web development
    專區

    :通過專門關於 Web 技術的文章和教程,擴充您在網站開發方面的技能。

  • developerWorks Ajax 資源中心

    :這是有關 Ajax 編程模型資訊的一站式中心,包括很多文檔、教程、論壇、blog、wiki 和新聞。任何 Ajax 的新資訊都能在這裡找到。

  • developerWorks Web 2.0 資源中心

    ,這是有關 Web 2.0 相關資訊的一站式中心,包括大量 Web 2.0 技術文章、教程、下載和相關技術資源。您還可以通過 Web 2.0 新手入門

    欄目,迅速瞭解 Web 2.0 的相關概念。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.