提高你的Javascript水平
前言

今天分享的這篇文章比較適合js初學者,是由堅持閱讀分享第一期的兩位童鞋翻譯與校對,他們分別是@安生與@墨白。整篇內容從模塊、代碼審查以及最后的測試上都做了介紹。
正文從這開始~
javaScripts是一種易學難精的編程語言。然而很多文章的內容都是假設你已經熟練掌握了js編程技巧。
在1995年javaScript作為LiveScript面世時,我就開始使用它了,但后來我逐漸從客戶端開發人員,轉到服務端安全的領域。。在過去的五年里,我重新關注客戶端開發。我驚喜地發現瀏覽器功能更加強大,也更容易調試。但JavaScript開始變得復雜且不易掌握。最近我轉變了自己的心態,沒必要去精通JavaScript,但我可以選擇讓自己js編寫水平更好。我很樂于成為一個“好”的JavaScript開發人員。
下面是一些我認為在編寫JS代碼方面很實用的技巧和技術,比如‘代碼組織’、‘代碼檢查’、‘測試’以及‘使用瀏覽器開發者工具’。其中一些對于有經驗的JS開發者來說是很簡單的事,但卻是新手非常容易養成的壞習慣。這些規范已經幫助我提高了我的技能,也給我的用戶帶來更好的體驗。這不正是我們的首要目標嗎?
組織
作為一個JS開發新人,不可避免地會在HTML頁面頂部放上一堆代碼。開始總是很簡單,一段簡單自動對焦到表單字段的jQuery,接著可能就是表單驗證,然后是網頁中常見的彈出框——就是那種會中斷人們閱讀內容,以便分享到FaceBook表示他們喜歡這個網站。經過一些迭代后就會變成幾百行的JS代碼,淹沒在有幾百行標記的HTML文檔里面。
這簡直一團糟,所以不要這樣做。這個聽起來很簡單,以至于我都認為不需要把它寫下來。但是,當你匆匆忙忙在趕一個快速腳本時,會非常容易在頁面的頂部形成堆積。為了避免這種情況,當你在制作一個新的網站時養成新建一個JS文檔的習慣。同時引用script腳本標簽,之后你就可以方便地添加交互或其他客戶端的特性了。
一旦你離開HTML頁面(有沒有感覺變得更加簡潔?),下一步就要組織代碼了。那些幾百行的JS代碼可能能夠運作,但你在幾個月后再次調試或修改時,你會發現你只是想單純找到一段函數而已。
所以如果簡單地從HTML中移動一些js代碼到其他文檔還不夠,下一步該做什么呢?
框架
很明顯框架是解決之道。把所有東西搬到AngularJS、Ember、React或者其他。重建整個網站成單頁面應用或者MVC會令人抓狂的。
或者并不需要?不要誤解,當我做App時我喜歡用Angular,但app和網頁之間有互動性方面的區別。Ajax-enhancedproduct catalog和Gmail也有區別——至少幾百行的代碼不同。但如果你不打算使用框架,會有什么其他的選擇呢?
設計模式
關于設計模式有一個說法就是“這是可以人們處理過去遇到的問題的經驗總結。”它們肯定是有用的。Addy Osmani寫了一本關于這個主題的好書——《學習JS設計模式》,你可以免費下載和閱讀我推薦的這本書。但關于這本書我有一個問題(以及對于這話題類似的討論),你可以看到像這樣的代碼:
理論上,設計模式對我來說是有意義的,但實際上并不。很難把它應用在一個實際的網頁上下文環境中。
模塊
在所有我閱讀過的模式中,我覺得模塊模式是最簡單以及最易適用于在現有代碼中的。
高層次的模塊模式會用一組代碼簡單地創造一個閉包。你可以用一個相關的集合函數,把它們放進一個模塊,然后選擇你想要公開的接口。這將創建更容易在其他項目的應用的“黑盒子”代碼。你也可以在模塊中將代碼移到不同的文檔。
來看一個關于模塊模式的簡單例子。我知道剛開頭會有個語法看起來很奇怪,不用著急,讓我們先來看下這個“容器”,我會解釋不同的點的:
會對這些圓括號感到疑惑嗎?老實說,盡管我了解JavaScript,我仍不是容易轉過圈來想明白它們在做些什么,于是,我換了一種思考方式,從代碼塊里面開始閱讀代碼。
從一個簡單的函數開始,在這里面定義的方法可以在模塊中調用.
最后一對括號會自動運行函數。我們會返回函數中定義的東西,當然現在它還是空的。但是高亮顯示的JavaScript代碼現在是無效的。那么如何讓它有效?
function(){}()里面的圓括號使得JS語句變得有效。不信可以打開你的開發者工具控制臺然后嘗試自己輸入。
回到一開始……
最后一件要做的事是把函數自動運行的結果賦給一個變量。盡管我個人完全明白這段代碼的含義,但每次我看到這段代碼我都會停下來,稍微提醒自己這段代碼的含義。不好意思提起,我在編輯器中保持著這段代碼,這樣我就可以復制和粘貼這段“空”模塊來進行快速復用。
既然我們已經明白了這種有點奇怪的語法,那么真正的模塊模式是什么樣子的呢?
前邊的代碼創建了一個叫做counterModule的模塊。它包括兩個函數:incrementCounter和resetCounter。運行可以看到:
想法就是打包好在counterModule里面的所有這些代碼。打包是入門級的東西,未來的JS會提供更加簡單的方法來做這些事情,但現在而言我發現模塊模式非常簡單,它是一種處理組織問題的簡單實用的方法。
一個實用的模塊例子
我們來構建一個可以匹配真實情境的簡單例子。我盡可能簡單地講,同時會有一些你可能會在實際的web應用中遇到的場景。
假設你的網絡游戲公司Lyntendo,有一個用戶注冊入口讓用戶創建游戲身份。你需要構建一個可供用戶選擇名字的表格。對于身份規則有些要求:
用戶名必須用大寫字母開頭。
用戶名必須要兩個字母及以上的長度。
允許空格,但不能有標點符號。
用戶名不能包括非主流詞匯。
首先,我們來寫一個非常簡單的表格。
以上提供了表格以及提交按鈕,同時也引進了描述規則的js文件,現在讓我們來看一下代碼。
從底部開始,我用一些基本代碼來獲取頁面中的元素(在這我沒有用jQuery),然后監聽按鈕的click事件。獲取用戶輸入的值然后把它傳到我寫的驗證方法中去。驗證輸入的值是否符合上面我描述的規則。代碼不太復雜,但當我的驗證規則增加并且我想在頁面中加入其它交互的點時,代碼就會變得復雜了。讓我們來重寫下這個模塊。
首先,創建一個新的js文件叫game.js,接著通過script標簽引用在我的index.html。然后我把描述驗證邏輯的內容放到一個模塊中。
這和之前并沒有太大區別,但現在它已打包好了放在gameMoudule的變量中,并且它有一個有效的API。現在看下app.js。
相比于之前的代碼,可以看到少混合了很多關于DOM監聽的代碼。所有驗證的功能(兩個函數和一個不符合驗證規則的壞詞列表)現在安全地放在模塊中,讓代碼更容易工作。在你的編輯器,你也可以完成代碼的模塊方法。
代碼模塊化不是必要和復雜的事,但它更簡潔和簡單,是非常好的東西!
代碼檢查
代碼檢查適用于在練習或其他問題中來檢查你的代碼。
你記得那些你重命名的函數然后提醒自己你會待會修補它的時候嗎?
你記得當你定義一個函數去接收兩個參數但最后卻從頭到尾只使用了一個的時候嗎?
你記得有時寫過一些非常愚蠢的代碼嗎?那些不能運行的,比如fuction和functon。
代碼檢查可以幫上忙。對于所有人來說,代碼檢查不只是好的練習,也可以是語法和基本的邏輯檢查。而且,利用代碼檢查工具幫助我們改正“我知道怎么修改代碼,等我有時間的時候再去修改代碼”這樣的壞習慣。所以,很多現代編輯器都有代碼檢查插件。我現在的編輯器(Sublime,Brackets,Visual Studio Code),所有都支持提供代碼檢測實時反饋。
舉個例子,這是一份VisualStudio Code的報告。我故意把一些代碼寫得很爛。
上圖Visual Studio Code報了我代碼中的一些錯誤。VSC的linter,和大多數的linters一樣,會提供關于你關心什么和你會認為什么是錯誤(“必須修復”)與警告(“別懶惰了,趕緊修復吧”)之間的選項。
如果你不想要安裝任何東西或配置你的編輯器,可以在JSHint.com進行在線代碼檢查。JSHint可能是最受歡迎的linter,它基于另一個linter:JSLint(兩者是不同的)。JSHint比JSLint嚴格的多。你可以直接在編輯器或通過命令行使用JSHint,當然,最簡單的使用方法就是在網頁上嘗試一下。
左邊的代碼是實時的編輯,右邊是關于左邊代碼的實時報告。簡單在代碼中引入一個低級錯誤就能大概清楚流程了。我把main函數改成main2:
站點立刻就報了兩個錯誤。但這些并不是語法錯誤。似乎上面的代碼看起來沒有問題,但JSHint注意到了你可能沒意識到的問題(這只是一個5行的代碼塊,但想象一下在一個偌大的文檔中到處都是函數而且被調用的函數分散在許多行中,人工檢查代碼會瘋的)。
那么實際的例子如何,下面的代碼中(現在使用jQuery了),是一些簡單的JS處理表單驗證。這種瑣碎的事,可能現在一半的JS代碼都在做(還有突然出現要求你點擊“喜歡”這個網站的模態框)。
這段代碼開頭寫了兩個函數來幫助驗證年齡和郵箱。然后我們有一個document.ready代碼塊來監聽表格提交。獲取來自三個區域的值,檢查是否空白(或無效),然后警告表格無效或者繼續執行(或者在我們的例子中,表格就這樣了)。
我們把這些放進JSHint然后看看可以獲得什么:
天吶,有好多問題,但是相似的問題發生了很多次,剛開始使用linters時是這樣。我并沒有特意制造許多獨特的錯誤,只是重復了許多相同的錯誤。第一個非常簡單——使用嚴格相等“===”來取代“==”。這里嚴格測試值是否是空字符串。好吧,我們先來修復它。
下面是JSHint里面更新的報告:
現在清楚了。下一個塊是關于“未定義的變量”。這看起來很奇怪,如果你使用過jQuery的話,你就會知道'$'。badForm存在的問題很簡單——我忘記用var給他設定范圍。但我們如何修復$呢?JSHint提供一個方法去配置代碼怎樣去檢查出問題。通過添加內容(類似注釋)到我們的代碼,我們可以讓JSHint知道$變量是作為全局存在的而且可以放心使用的。
然后是JSHint的更新報告:
啊,終于快完了。最后問題是一個很好的例子,這個例子說明了JSHint可以提供除了代碼錯誤之外的信息。在這個例子中,我忘寫了一個處理年齡核實的函數。我已經創建了validAge,但在表格檢查區域,并沒有調用它。函數雖然只有一行,但可以以防后面驗證更繁雜,所以我決定保留它。這是最終的代碼版本(demo_jshint/app.js)
這個版本最終“通過了”JSHint的測試。這個代碼還不是完美的。現在有validAge和invalidEmial這兩個驗證函數。如果通過驗證的話,兩個驗證函數的返回值不同,一個是true,一個會是false。如果返回值是一致的會更好。同樣認識到每次驗證運行,jQuery都會被獲取來自DOM的三個節點。
它們只需要加載一次。我應該創建一些變量在提交塊之外,然后每次都來復用它們。就像前邊說的,JSHint不是完美的,但經過JSHint檢測的最終版本肯定會比最開始的更好,而且也沒有花費很多時間來修改代碼。
關于代碼檢測工具,有JS的linters(JSLint和JSHint),HTML的linter(HTMLHint和W3C Validator),CSS的linters(CSSLint)。伴隨著編輯器的支持,如果你喜歡的話也可以使用自動化工具,比如Grunt和Gulp.
測試
首先,許多編輯器會自動測試你的代碼。比如說,在Brackets,你可以使用xunit擴展,右鍵單擊JS文檔然后生成一個測試
這個擴展會嘗試根據代碼寫一個測試。這個測試會一直存在著而你需要更新一些實際的數據,但最重要的是它會幫助你減少繁重的測試工作。
一旦你開始更新細節,擴展會自動運行你的測試。現在知道寫測試很重要了吧?
你可能聽過TDD(Test DrivenDevelopment)。這是一個概念,描述的是在開發實際功能之前編寫單元測試。從本質上說,就是測試驅動開發。當你寫完代碼并且代碼通過測試時,你可以確保你的方向是對的。
想象你有一組還可以運行的現有代碼,然后你發現了一個bug。在你修復bug之前,你可以寫一個測試去驗證這個漏洞,然后修復它。之后確保在你未來工作中也能通過這個測試將它修復。這不是一個理想的路徑,但可以是一種漸進增加到包括測試的所有開發階段的方法。
在這個示例中有一個簡化數字的小函數。在這個樣例里109203可以被簡化為109K。而210290可以轉化為2M。看下這段代碼,我們一起來找一找有沒有bug:
當輸入9999,它會返回1萬。現在看起來簡化是有效的,但這段代碼把所有小于1萬的數字都返回它們的自身的值。這很容易修正,不過,我想為它嘗試寫一個測試來作為示范。測試框架使用Jasmine。Jasmine可以用通俗易懂的語言去寫測試,并且很容易進行執行操作。最快的方法就是下載一個庫。一旦完成并提取,會發現有一個SpecRunner.html的文檔。這個文檔處理加載你的代碼,加載你的測試,然后執行測試并創建報告。它需要壓縮包里面的lib文件夾,但你可以復制SpecRunner和lib到你的web服務端。
打開SpecRunner.html然后你可以看見最上面寫著:
在第一行內容下面你會想要刪除現有行然后簡單加上一個scipt的標簽指向你的代碼。如果你得到這篇文章的壓縮包你可以看見我的代碼在demo4的文檔中有一個formatter.js。接下來你會想要添加一個script標簽去指向spec或者測試。可能你還沒見過Jasmine,但看下spec。它非常易讀。
基本上我的測試是在說當9999傳送到庫時,它應該輸出9999才對。如果你在瀏覽器打開SpecRunner.html你可以看見它報錯了。
這個修復簡單點。改變9999為10000條件。
現在你運行下就會有比較好的結果的了:
查看模塊,你可以嘗試把一些相關的測試寫成組件。在實際項目中,盡量認真測試和盡可能的覆蓋到每一種可能。嘗試下一個很棒的日期/時間庫館Moment.js,有超過五萬七千的測試。
其他關于測試的JS代碼的選擇包括Qunit和Mocha。在代碼檢查你可以對任務的執行自動測試,像Grunt,你甚至可以在完整的前后端環境下通過用Selenium測試瀏覽器來測試你的項目。
瀏覽器開發者工具
最后一個我會提到的工具就是在瀏覽器里邊的——開發者工具。你可以找到許多關于這個話題的文章、介紹和視頻,所以我不會講太多,除此之外我相信,這或者是一件我認為對web開發者來說的“必備知識”。你不知道的話也無所謂。但瀏覽器開發者工具至少可以幫助你找到關于錯誤的信息,此時的解決方案通常是谷歌一下。
最后一點的小建議,那就是不應該只關注到一個瀏覽器開發者工具。我在幾年前就嘗試了應用程序緩存,然后把我的代碼放到Chrome中來查看問題。我也有打開我自己的開發者工具,但它不起作用。心血來潮我就打開代碼到FireFox并使用它們的開發者工具,很快就找到了問題所在。相比于Chorme,Firefox報告更多的信息。運行一次就足以讓我修正問題了(好吧,我騙你的,Firefox告訴我問題所在但修復的時間會有點長。)如果你被困住了,只需打開另一個瀏覽器然后看看它所提供的不同角度的錯誤報告。
如果沒使用過你的瀏覽器工具,這里是一些關于如何在主流瀏覽器查看它們的操作指南。
Google Chrome
打開開發者工具,點擊瀏覽器右上方的漢堡菜單圖標,選擇“更多工具”,然后“開發者工具”。也可以用鍵盤打開,比如在OSX中組合鍵是CMD+SHIFT+C。你可以在“Chrome DevTools Overview”找到Chrome開發者工具的文檔。
Mozilia Firefox
打開開發者工具,在主菜單找到“工具”,然后點擊“網站開發者”和“切換工具”。注意Firefox有一個很酷的工具欄可以用來發出命令以及打開開發者工具。這個同樣可以從相同的菜單中啟用。你可以在Firefox Developer Tools學到更多。
Apple Safari
在你能使用開發者工具工作之前,你必須啟用“開發”菜單。到Safari的偏好設置,然后選擇“優先”,單擊“在主欄顯示開發菜單”。接著你可以選擇“開發”菜單,然后使用“顯示Web檢測”(或者下面的三個條目)來打開開發者工具。你可以在“About Safari Web Inspector”閱讀更多。
IE
點擊右上角的齒輪圖標(或按下F12)打開IE的開發者工具,你可以在“Using the F12 developer tools”閱讀更多。
學習吧
作為開發者,有時似乎我們的工作從來沒有完成的那一刻。當寫這篇文章時,已經有超過13個的JS框架被制造出來了。所以最后有一些關于如何盡可能學習的建議。
關于學習,我主要在MozilaDeveloper Network(當你谷歌時,前面要加上一個“mdn”),CodeSchool(一個培訓公司很好的商業視頻),和Khan Academy。我想要專門拿MozillaDeveloperNetwork(MDN)出來講,之前我愚蠢的以為它只是一個Netscapr/Firefox的站點而一直沒使用它。
另一個建議是閱讀代碼。我們中的大部分人用過jQuery,但你們有沒真真切切打開文檔看下它是怎么寫的?閱讀其他人的代碼是發現其他技術和理論的很好途徑。強烈鼓勵你分享你的代碼。不只因為你會有別人幫你review代碼,你可能也會幫助到別人。幾年前我看過一個初級程序員分享了一些代碼,他出現了一些典型的新手錯誤,但他也用了一些很棒的技術呀。
為了跟緊當下的新聞,我通過CooperPress訂閱了各種每周通訊。他們有HTML周報,JS周報,Node周報,Mobile周報等等。這樣的資源很多,但要量力而行。當看見一些新的工具發布后,可能那時候我不需要它,我就不會去試著使用,但會記在腦海里說“有一個工具叫做……”,這樣我將來需要用到的時候就能用上了。
關于本文
譯者:@安生
校對:@墨白
本文轉載自異步社區
JavaScript 代碼檢查 CodeCheck
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。