編寫可維護的JavaScript
技術支持服務電話:15308000360 【7x24提供運維服務,解決各類系統/軟硬件疑難技術問題】
在我的編程生涯中,曾遇到過各種各樣的開發者,他們的編程風格天馬行空,有時甚至讓人哭笑不得。有一種風格被稱為“霰彈槍編程”,例如某個方法調用出錯了,我嘗試將參數0改為'0'、NaN甚至false,直到試出能“正確”運行的參數為止。當你和這種人組成團隊一起編程時,你會發現你的智商變得很低。
比“霰彈槍編程”更溫柔一點的編程方式是“撞大運編程”,就是我根本看不懂程序到底在干嘛,但確實能正常運行,這往往是因為這些程序中有很多錯誤成對出現,于是就負負得正,看起來就正確了,這種程序實在是“動彈不得”,只能重構。當你和這種人組成團隊時,上帝都會同情你。
當然,當漸漸意識到這類隨意編程風格帶來的危害時,很多人開始思考什么才是“好”的編程風格。不少人開始向高手學習,盡管有時并不知道高手為什么要把代碼寫成這個樣子。于是越來越多的hack代碼出現了,那些看起來晦澀難懂、短小精悍卻又暫時行之有效的代碼片段越來越流行,尤其是在處理瀏覽器兼容性問題時,這種情況更甚。有些人會在這些hack代碼片段旁邊打上記號,以便以后有問題時能留意到此。這時,問題又出現了,不同人做記號的方法又不一樣,我的天哪!
如果你自詡為一名有能力有良知的程序員,遇到這種“爛”代碼時往往將之重構,為了修改幾個拼寫錯誤的bug,而修改10個類,并且重構與這10個類有關聯的另外20個類,甚至修改了打包腳本以及部署配置文件。這就是一種有著代碼潔癖的人很“青睞”的編程風格—“屠宰式編程”。
霰彈槍式、撞大運式、不求甚解式、屠宰式……
編程是一項復雜的工程,卻又如此充滿喜感,讓人又愛又恨。但有一點確定無疑,即這些風格因為缺少基本的約束,會導致團隊協作效率低下,甚至影響產品的存亡。而對于Web開發領域最為流行卻有著先天設計缺陷的語言JavaScript來說,情況更加糟糕。一直以來都缺少宏觀的設計模式和微觀的編程風格的指導,從而導致JavaScript編程始終沒有權威和統一的指導思想和方法論。因此,大部分Web前端團隊依然將很大精力放在解決注入代碼沖突、命名規范性、代碼復用模式等團隊編程最基本的問題上。遲遲走不上創新、高效的快車道。
我們很欣喜地看到,在設計模式領域,《JavaScript設計模式》(JavaScript Design Patterns)和《JavaScript編程模式》(JavaScript Patterns)兩本書填補了這方面的空白,而在編程風格領域,這本《編寫可維護的JavaScript》(Maintainable JavaScript)真可謂姍姍來遲。
本書正是向開發人員闡述如何在團隊開發中編寫高可維護的JavaScript代碼,涵蓋了編碼風格、編程技巧、自動化、測試等幾方面,不過,同樣的原則也適用于其他任何語言。本書作者是大名鼎鼎的Nicholas C. Zakas。他曾是Yahoo!的首席前端開發工程師,在完成了從一名獨行俠到團隊精英的蛻變后,他站在前端工程師的角度為我們提煉出許多的最佳編程實踐,其中包括很多來自工業生產的最佳法則。應用這些技巧和技術,可以使你的團隊編程從俠義的個人偏好的陰霾走出來,走向真正的高效和高水準。
本書由淘寶北京前端團隊翻譯,在翻譯過程中,我們始終保持一種學習的心態,因為正像前面提到的,作者給出的很多經驗正是我們手頭工作中不在意卻又至關重要的,這種學習心態也讓我們在這次翻譯過程收獲頗豐。我們盡最大的努力,力求翻譯后的表述在還原作者原意的同時又不失中文的流暢。但難免由于譯者水平有限而有所紕漏,還請各位高手多多批評指正。
序言
由于前端工程師的成長道路自成軌跡,這讓(Web前端技術)這個專業看起來是如此的與眾不同,甚至諸如Yahoo!這種大公司里的很多前端工程師也多是靠自身野蠻生長,我行我素地寫著各種hack! ?;蛟S你曾經也是一名小公司里的“頁面仔”(the web guy),那時的你幾乎什么都干。當大公司開始利用這些之前未被發掘的資源時 ,團隊協作的環境短時間內吸納了很多“hacker” ,這時這些hacker碰到了各種條條框框。單兵作戰再也沒了優勢,所有那些自學成才和以自我為中心的人都不得不開始思考如何才能在團隊環境中生存下來。
我是在20世紀90年代末開始學習JavaScript的:靠的是自學。因為當時的JavaScript還很新潮,學習資料很少。和其他很多開發者一樣,我通過不斷鉆研IE和Netscape Navigator來自學。我做各種嘗試、梳理我所掌握的知識,我一遍遍反復試驗,直到搞清楚其工作原理。幸運的是,這份好奇和勤勉為我帶來了第一份工作。
在我職業生涯的第一個五年中,我是一個“腳本仔”。在我最早呆過的兩家公司里,沒有人比我更了解JavaScript和Web開發。所有問題,不管是非常簡單的還是非常復雜的,我都能搞定。我剛剛從學校畢業,是一名初出茅廬的小伙子,卻有著一種危機感。因為我找不出能和我產生思想碰撞的人,并且在我遇到問題時也沒有人能為我解難。我力爭做到最好,因為我知道我是唯一能做到這樣的人。
在這五年之中,我不斷磨煉我的技能。我讓我的做事方式和工作流程更為合理。我不用擔心其他人去研究我的代碼,因為別人都沒有能力給我做代碼評審(review)或為我的代碼提交bug修復。我是一個純粹意義上的hacker:我行我素地寫著代碼,而且不用擔心它會被修改。
在我職業生涯的第六年,我換了工作,加入了一個團隊,在這個團隊中,每個人都會為項目的各個方面貢獻代碼。我的主要精力不再是JavaScript和Web開發,而是大部分時間在寫后端代碼和SQL。同時,傳統的后端工程師卻開始被迫寫前端(頁面)代碼。這種體驗真正讓我大開眼界:我之前寫代碼的方式和團隊其他人實在是格格不入,這是一個大問題。
我很快意識到要想更高效地參與團隊開發,我寫代碼的方式必須和團隊保持一致。后臺代碼和SQL對我來說有點陌生,因此我采納了身邊一些有頭腦的人寫代碼的模式。與此同時,我開始與其他工程師討論我們應當采納何種HTML、CSS和JavaScript的編程模式。我甚至在編譯階段加入了JavaScirpt語法檢查來強制推行標準—這也是我第一次在公司做 Web 代碼的檢查。不久以后,這個團隊就像上了潤滑油的機器一樣高效。
我在2006年加入了Yahoo!。我一到Yahoo!就發現幾乎所有工作都和相互協作有關。整個團隊就像把不同的動物糾集在一起。我所加入的第一個團隊是My Yahoo!團隊,這個團隊非常龐大,比我之前工作過的任何團隊都要大。團隊里也有很多成型的編程指南,我有很多需要學習的東西。新技術、新流程以及新工具一股腦地展現在我面前。我花了大量的時間來學習這些新環境,吸收新知識,而這些知識是我從大學里接觸不到的。在這里我完全沉浸在知識的海洋里,感覺自己像被重塑了一般。
幾個月后,我開始遇到一些問題。我所習慣的開發流程并不是總能好好工作。有不少人以不同的方式來做事,這導致了很多bug。我的主管發現了這一苗頭,一天他把我叫到一邊,告訴我他希望我來負責梳理我們的開發?,F在回想起他的話依然是那么鼓舞人心:“你寫的代碼都可以運行得很好,很少出bug。我希望其他人都像你一樣寫代碼。”就這樣,我打算著手為My Yahoo!前端開發團隊注入一些結構和規范。
我為My Yahoo!團隊做的工作非常成功,最終我被遴選為2008年Yahoo!新版首頁的首席前端工程師。這次委任讓我有機會將代碼組織和測試高質量代碼的技巧,應用于一個擁有20名前端工程師的團隊,讓這20名工程師只開發一種(風格的)代碼。通過幾個月的學習和調整,這個團隊的生產效率和產品質量達到了一個很高的水平,讓很多人嘆為觀止。不管是誰寫的代碼,它們都看起來像出自一個人之手,此外,多數工程師都可以快速地接手別人的工作來修復bug或開發新功能。在此期間,作為一個工程師團隊所產出的業績,在過去的幾年里一直是我職業生涯的最大亮點。
我在Yahoo!的這段時間都是在參與大型的團隊開發,我將在此期間積累的所有經驗和方法整理出來成書于此。所討論的主題也體現了我的這種蛻變,我從一名我行我素的獨行俠,蛻變為一名軟件工程師,一名團隊協作者,我放棄了我身上固有的俠氣和個性,來讓整個團隊以更高的水準運作。這正是這本書的內容:如何站在團隊的角度去寫JavaScript代碼。
開發者最不容易理解的事情是,我們為何需要花這么多時間來“維護”代碼。很少有人會打開一個文本編輯器從頭開始寫代碼。大多數時間里,你面對的都是已經寫好的代碼。以一種可維護的方式來寫代碼,可以讓你和協作者很容易就知道上段代碼寫到什么地方什么程度。正如我在Yahoo!時常說的:“當你開始工作時,你不是在給你自己寫代碼,而是為后來人寫代碼。”
本書收集了很多關于JavaScript編程規范的討論。“Java語言編碼規范”(Code Conventions for the Java Programming Language) 是當前最流行的關于編碼規范的文檔之一,它指出編碼規范如此重要的幾個原因。
軟件生命周期中80%的成本消耗在了維護上。
幾乎所有的軟件維護者都不是它的最初作者。
編碼規范提高了軟件的可讀性,它讓工程師能夠快速且充分地理解新的代碼。
如果你將源碼作為產品來發布,你需要確保它是可完整打包的,且像你創建的其他產品一樣整潔。
這些原因在今天看來依然適用。本書所討論的編程規范也是著眼于幫助你和你的團隊寫出高效的JavaScript代碼。
因為你正在閱讀這本書,你需要對本書提到的一些建議保持開放的心態。要知道這里說的很多技術,真正的目標是解決多人開發的環境中很多工程師如何書寫統一風格的代碼的問題。作為團隊的一員,意味著做出這種決策不僅對個人有好處,對于團隊也同樣有好處。對于個人來說,需要在一定程度上犧牲個人偏好、個人觀點甚至個人英雄主義。你所收獲的是一個能做大事的高效的團隊,我希望這本書可以幫助你做到這一點。