第20章 最佳實踐 (一)

 

自從2000以來,Web開發方面的種種規範、條例正在高速發展。過去曾是荒蕪地帶,裏面東西還都湊合,而現在已經演化成了完整的研究規範,並建立了種種最佳實踐。隨着簡單的網站成長爲更加複雜的 web 應用,同時 web 愛好者成爲了有收入的專業人士,web 開發的世界充滿了各種關於最新技術和開發方法的信息。尤其是 JavaScript ,它從大量的研究和推斷中獲益。JavaScript 的最佳實踐分成若干類,並在開發過程的不同點上進行處理。

20.1 可維護性

在早期的網站中,JavaScript 主要是用於小特效或者是表單驗證。而今天的 web 應用則會有成千上萬行 JavaScript 代碼,執行各種複雜的過程。這種演化讓開發者必須得考慮到可維護性。除了秉承較傳統理念的軟件工程師外,還要僱傭 JavaScript 開發人員爲公司創造價值,而他們並非僅僅按時交付產品,同時還要開發智力成果在之後不斷地增加價值。

編寫可維護的代碼很重要,因爲大部分開發人員都花費大量時間維護他人代碼。很難從頭開始開發新代碼的,很多情況下是以他人的工作成果爲基礎的。確保自己代碼的可維護性,以便其他開發人員在此基礎上更好的開展工作。

注意可維護的代碼的概念並不是 JavaScript 特有的。這裏的很多概念都可以廣泛應用於各種編程語言,當然也有某些特定於 JavaScript 的概念。

20.1.1 什麼是可維護的代碼

可維護的代碼有一些特徵。一般來說,如果說代碼是可維護的,它需要遵循以下特點:

  • 可理解性 -- 其他人可以接手代碼並理解它的意圖和一般途徑,而無須原開發人員的完整解釋;
  • 直觀性 -- 代碼中的東西一看就能明白,不管其操作過程多麼複雜;
  • 可適應性 -- 代碼以一種數據上的變化不要求完全重寫的方法撰寫;
  • 可擴展性 -- 在代碼架構上已經考慮到在未來允許對核心功能進行擴展;
  • 可調試性 -- 當有地方出錯時,代碼可以給與你做夠的信息來儘可能直接地確定問題所在。
對於專業人士而言,能寫出可維護性的 JavaScript 代碼是非常重要的技能。這正是週末改改網站的愛好者和真正理解自己作品的開發人員之間的區別。

20.1.2 代碼約定

一種讓代碼變得可維護的簡單途徑是形成一套 JavaScript 代碼的書寫約定。絕大多數語言都開發出了各自的代碼約定,只要在網上一搜就能找到大量相關文檔。專業的組織爲開發人員制定了詳盡的代碼約定試圖讓代碼對任何人都可維護。傑出的開放源代碼項目有着嚴格的代碼約定要求,這讓社區中的任何人都可以輕鬆地理解代碼是如何組織的。
由於 JavaScript 的可適應性,代碼約定對它也很重要。由於和大多數面嚮對象語言不同,JavaScript 並不強制開發人員將所有東西都定義爲對象語音可以支持各種編程風格,從傳統面向對象式到聲明式到函數式。只要快速瀏覽以下一些開源 JavaScript 庫,就能發現好幾種創建對象、定義方法和管理環境的途徑。
以下小節將討論代碼約定的概論。對這些主題的解說非常重要,雖然可能的解說方式會有區別,這取決於個人需求。
1.可讀性
要讓代碼可維護,首先它必須可讀。可讀性與代碼作爲文本文件的格式化方式有關。可讀性的大部分內容都是和代碼的縮進相關的。當所有人都使用一樣的縮進方式時,整個項目中的代碼都會更加易於閱讀。通常會使用若干空格而非製表符來表示縮進,這是因爲製表符在不同的文本編輯器中顯示效果不同。一種不錯的、很常見的縮進大小爲4個空格,當然你也可以使用其他數量。
可讀性的另一方面是註釋。在大多數編程語言中,對每個方法的註釋都視爲一個可行的實踐。因爲 JavaScript  可以在代碼的任何地方創建函數,所以這點常常被忽略了。然而正因爲如此,在 JavaScript 中爲每個函數編寫文檔就更加重要了。一般而言,有如下一些地方需要進行註釋。
  • 函數和方法 -- 每個函數或方法都應該包含一個註釋,描述其目的和用於完成任務所可能使用的算法。陳述事先的假設也非常重要,如參數代表什麼,函數是否有返回值 (因爲這不能從函數定義中推斷出來)。
  • 大段代碼 -- 用於完成單個任務的多行代碼應該在前面放一個描述任務的註釋。
  • 複雜的算法 -- 如果使用了一種獨特的方式解決某個問題,則要在註釋中解釋你是如何做的。這不僅僅可以幫助其他瀏覽你代碼的人,也能在下次你自己查閱代碼的時候幫助理解。
  • Hack -- 因爲存在瀏覽器差異,JavaScript 代碼一般會包含一些 hack。不要假設其他人在看代碼的時候能夠理解 hack 所要應付的瀏覽器問題。如果因爲某種瀏覽器無法使用普通的方法,所以你需要用一些不同的方法,那麼請將這些信息放在註釋中。這樣可以減少出現這種情況的可能性:有人偶然看到你的 hack ,然後 "修正" 了它,最後重新引入了你本來修正了的錯誤。
2.變量和函數命名
適當給變量和函數其名字對於增加代碼可理解性和可維護性是非常重要的。由於很多 JavaScript 開發人員最初都只是業餘愛好者,所以有一種使用無意義名字的傾向,諸如給變量起 "foo" 、"bar" 等名字,給函數起 "doSomething" 這樣的名字。專業 JavaScript 開發人員必須克服這些惡習以創建可維護的代碼。命名的一般規則如下所示。
  • 變量名應該爲名詞如 car 或 person。
  • 函數名應該以動詞開始,如 getName()。返回布爾類型值的函數一般以 is 開頭,如 isEnable()。
  • 變量和函數都應使用合乎邏輯的名字,不要擔心長度。長度問題可以通過後處理和壓縮來緩解。
必須避免出現無法表示所包含的數據類型的無用變量名。有了合適的命名,代碼閱讀起來就像講述故事一樣,更容易理解。
3.變量類型透明
由於在 JavaScript 中變量是鬆散類型的,很容易就忘記變量所應包含的數據類型。合適的命名方式可以一定程度上緩解這個問題,但放到所有情況下看,還不夠。有三種表示變量數據類型的方式。
第一種方式是初始化。當定義了一個變量後,它應該被初始化爲一個值,來暗示它將來應該如何應用。例如,將來保存布爾類型值的變量應該初始化爲 true 或者 false,將來保存數字的變量就應該初始化爲一個數字,如以下例子所示:
// 通過初始化指定變量類型
var found = false;              // 布爾值
var count = -1;                    //  數字
var name = "";                    // 字符串
var person = null;              // 對象
初始化爲一個特定的數據類型可以很好的指明變量的類型。但缺點是它無法用於函數聲明中的函數參數。
第二種方法是使用匈牙利標記法來指定變量類型。匈牙利標記法在變量名之前加上一個或多個字符表示數據類型。這個標記法在腳本語音中很流行,曾經很長時間也是 JavaScript 所推崇的方式。JavaScript 中最傳統的匈牙利標記法是用單個字符表示基本類型: "o" 代表對象, "s" 代表字符串, "i" 代表整數, "f" 代表浮點數, "b" 代表布爾值。如下:
// 用於指定數據類型的匈牙利標記法
var bFound;                    // 布爾型
var iCount;                      // 整數
var sName;                     // 字符串
var oPerson;                   // 對象
JavaScript 中用匈牙利標記法的好處是函數參數一樣可以使用。但它的缺點是讓代碼某種程度上難以閱讀,阻礙了沒有用它時代碼的直觀性和句子式的特質。因此,匈牙利標記法失去了一些開發者的寵愛。
最後一種指定變量類型的方式是使用類型註釋。類型註釋放在變量名右邊,但是在初始化前面。這種方法是在變量旁邊放一段指定類型的註釋,如下:
// 用於指定類型的類型註釋
var found /*:Boolean*/ = false;
var count /*:int*/  = 10;
var name /*:String*/ = "Nicholas";
var person /*:Object*/  = null;
類型註釋維持了代碼的整體可讀性,同時注入了類型信息。類型註釋的缺點是你不能用多行墜飾一次註釋大塊的代碼,因爲類型註釋也是多行註釋,兩者會衝突,如下例所示:
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章