編寫可維護的JavaScript

jopen 9年前發布 | 16K 次閱讀 JavaScript開發 JavaScript


每次亞馬遜或者京東滿xxx打折的時候,總會湊單擼各種奇怪的不知道哪年才會翻開來看看的書(大家不是都這樣么:) )。前兩天給同事 code review JavaScript 代碼,由于我經驗不豐富,看著總覺得心里沒底。轉眼瞥見書架上夾著一本 《編寫可維護的 JavaScript》 ,雖然怎么想也想不起是什么時候買回來的,但記得 Sneezry 老師推薦過本書,便立馬拿出來翻了翻。

作者 Nicholas C.Zakas 曾是 Yahoo! 的首席前端開發工程師(現在跑到 Box 去了),在書中介紹了編程風格、編程實踐和自動化方面的 best practice 。大師果然就是大師啊,短短數小時內,我便產生了深深的共鳴,腦洞也各種大開。內心的喜悅不能獨享,我決定為它寫篇博文,講一講其中的“高光時刻”。

編程風格

本書的第一部分講解如何使用統一的編程風格,降低團隊項目的維護成本。幾乎每一門語言都有自己的 styling rule ,靠譜的技術企業甚至會在企業內部推行的自己的編程風格(比如在 baidu 寫 C++ )。

當我們談論風格時,我們其實是在說

  • 縮進
  • 換行
  • 行的長度
  • 花括號的對齊
  • 注釋
  • 命名
  • etc

你幾乎可以在每一本語言書上找到這些章節。書中推薦使用 JSHint JSLint 等編程風格檢查工具,個人覺得,選擇其中一種并且推行下去既可以了,事半功倍。

編程實踐

這一部分就是講編程過程中的 best practice

UI層的松耦合

我們知道在Web開發中,用戶界面由 HTML, CSS 和 JavaScript 三層一起構建的

  1. HTML 定義頁面數據和語義
  2. CSS 給頁面添加樣式,創建視覺特征
  3. JavaScript 用來給頁面添加行為

我們應當努力減少這三層之間的依賴性,讓更改單獨修改某個組件時無需修改其他組建。作者給出的建議,有這幾條我覺得值得牢記

  1. 將 CSS 從 JavaScript 中抽離。舉一個實際的栗子,我們經常在頁面上實現 lazy loading,在 request 發送出去之后,我們會秀出一張菊花圖提示用戶正在加載,加載完畢后,隱藏或者刪除掉這個張菊花圖。最直接的做法就是在 ajax call 前后調整這張圖片的 display 屬性。但是這么做會帶來一個問題,樣式是由 JavaScript 而非 CSS 來加載的,當出現樣式的問題時,我們會第一時間查看 CSS,但?最直 當我們查到精盡人亡的時候,我們才發現樣式是由 JavaScript 改變的,一定會哭的。Best practise 是把所有樣式保留在 CSS 中,當需要用 JavaScript 來修改元素樣式時, 操作 CSS 的 className (計算元素定位例外)。
  2. 將 JavaScript 從 HTML 中抽離。很多初學者都會把腳本嵌入到 HTML 中來運行,比如在 element 上綁定 onclick 屬性或者使用<script>標簽。在這種情況下,當你需要更新這個方法的命名,你總需要更新 HTML 頁面;內嵌的 JavaScript 會給調試和 troubleshoot 帶來難度(至少是增加了復雜度)。Best practise 是 把絕大多數的** JavaScript 代碼放在外部文件中**。
  3. 將 HTML 從 JavaScript 中抽離。模版化發展到今天,這條規律幾乎不言自明了。

避免空比較

這個比較繞口,舉個例子大家就明白了,通暢我們設計一個函數時,需要考慮傳進來的參數是否正確,比如不能為空,不能為 undefined 。像下面這段代碼:

function Process(items) {
  if (items !== null) {
      items.sort();
    items.forEach(function (item) {});
  }
}

事實上在這段代碼中,我們真正關心的是 items 這個 object 是否為一個 Array 。單純的和 null 進行比較,代碼的可讀性不好,coverage 也不夠。本書的建議是,使用諸如 typeof, instance of 等來檢測原始值( primitive value)、引用值和函數等。

if (typeof name === "string") {
 }

上面的代碼就清晰的交代了函數期待 name 這個 variable 是一個 string 而非其他類型的值。

其他

這一部分其他章節,個人覺得在其他編程語言中也基本適用,比如

  • 避免使用全局變量
  • 使用命名空間和模塊
  • 將配置數據從代碼中分離出來
  • 自定義 error

或者比較 hacky,比如 瀏覽器嗅探。讀者可以在互聯網上找到更全面的解決方案。

自動化

第三部分,作者花了八個章節來講解如何對前端代碼進行開發、測試、部署、文檔的自動化。作者寫這本書的時間距離現在已經過去數年,前端自動化已經逐漸成熟并且被廣泛接受,你一定或多或少見到過以下工具

  • Task Runner. Grunt/Gulp,這兩個工具其實代表的是一套工具鏈,比如代碼合并(concat),代碼壓縮(minification),代碼風格審查( JSHint/Lint)等等,然后通過 task runner 將這些工具組合到一起。
  • CI. Jenkins/TeamCity
  • Test Framework. Protractor/Selenium
  • etc…

如果你們的前端團隊還沒有使用到上面提到的任何工具(或者自己造了類似的輪子),那情況可能就有點不妙了。

放在最后

不管我自己是否承認,我已經成為了一個半路出家的前端工程師了,和我最先估計的職業生涯路線有點偏差。我司大部分部門招人的策略是招聰明的人而非招專業的人,這就導致了來我司前你耍什么技術已經不那么重要。過去我司比較保守,一定要 dogfood,大家來了就只能使用 .NET,使用開源或者別家的技術十分謹慎。但是這兩年突然 open 起來了,按照需求你可以自由地選擇前端框架(像我們就用 Angular)、緩存(Redis已經稱為第一選擇,大阿哥AppFabric被廢黜了)、搜索引擎(elastic search 大家都得用啊)、測試框架(Selenium已經接連KO VS測試框架和MTM)等等等等,不知不覺中人人都變成了全棧工程師。也不知道這算不算好事。

簡言之,讀者朋友們不太可能在我的博客上看到 .NET 的文章了,讓你們失望啦 :)

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!