解開意大利麵條代碼:編寫可維護的JavaScript
本文由湯姆·格雷科(Tom Greco),丹·普林斯(Dan Prince)和Yaphi Berhanu進行了同行評審。感謝SitePoint所有的同行評審員製作SitePoint內容的最佳狀態! >幾乎每個開發人員都有維護或接管舊項目的經驗。或者,也許這是一個舊的項目,再次被接管了。常見的第一想法是丟棄代碼庫,然後從頭開始。該代碼可能是混亂的,無證的,可能需要幾天才能充分理解所有內容。但是,通過適當的計劃,分析和良好的工作流程,可以將意大利麵條代碼庫變成乾淨,有條理且可擴展的一個。
>我不得不接管並清理許多項目。我從頭開始沒有很多。實際上,我目前正在確切地說。我學到了很多有關JavaScript,保持代碼庫的組織,最重要的是 - 在以前的開發人員中沒有瘋狂。在本文中,我想向您展示我的步驟,並告訴您我的經驗。
鑰匙要點
- 首先了解項目:在進行編碼之前,徹底分析現有代碼庫,了解所使用的技術和工具,並研究任何可用的文檔或單位測試,以更深入地了解該項目的功能。 >
- 建立一個一致的編碼標準:實現“ .editorConfig”文件,以維持不同開發人員使用的各種編輯器和IDE的一致編碼樣式。這包括一致的凹痕和遵守命名慣例。
- >實施刺傷工具:使用諸如ESLINT之類的JavaScript Linter來執行編碼標準和最佳實踐,確保代碼質量並幫助在開發過程的早期識別和修復錯誤。 明智地管理依賴性:謹慎地更新項目依賴性,了解主要,次要和補丁版本的變化的含義,以避免將新錯誤引入項目。
- 重新謹慎的重構:專注於在適當的情況下模塊化代碼庫,將復雜功能分解為遵循單個責任原則的較小,可管理和可重複使用的模塊。 >文檔並定期提交:使用JSDOC進行全面的文檔,並通過定期承諾進行有組織的提交工作流程,以跟踪更改並在必要時促進回滾。始終在與大師的單獨分支上工作,以有效地管理重構和新功能。
- >
- 分析項目
找出正在使用的工具。 jQuery?反應?表達?列出所有重要的知識。假設該項目是用Angular 2編寫的,您尚未與之合作,直接介紹文檔並獲得基本的理解。搜索最佳實踐。
了解更高級別的項目
知道這些技術是一個不錯的開始,但是要獲得真正的感覺和理解,是時候研究單元測試了。單元測試是測試功能和代碼方法的一種方法,以確保代碼的行為按預期行為。閱讀和運行 - 單位測試比僅閱讀代碼更深入地了解。如果他們在您的項目中沒有單位測試,請放心,我們會來的。
>創建一個基線
這就是建立一致性。現在,您已經擁有有關項目工具鏈的所有信息,您就知道了結構以及邏輯如何連接,現在該創建基線了。我建議添加一個.editorConfig文件,以保持編碼樣式指南在不同的編輯器,IDE和開發人員之間保持一致。
連貫的凹痕>著名的問題(儘管應該使用空格或標籤,但
戰爭 )無關緊要。代碼庫是用空間寫的嗎?繼續空間。有標籤?使用它們。只有當代碼庫具有混合凹痕時,才有必要決定要使用哪種。意見很好,但是一個好的項目可以確保所有開發人員都可以在沒有麻煩的情況下工作。
>為什麼這甚至重要?每個人都有自己使用編輯器或IDE的方法。例如,我是代碼折疊的忠實擁護者。沒有該功能,我實際上會丟失在文件中。當凹痕不連貫時,此功能會失敗。因此,每次打開文件時,我都必須在開始工作之前修復縮進。這是一個巨大的時間浪費。
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
>命名
確保尊重項目中使用的命名慣例。駱駝通常在JavaScript代碼中使用,但我看到了很多混雜的慣例。例如,jQuery項目通常具有jQuery對像變量和其他變量的混合命名。
><span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
覆蓋所有內容
>前面的步驟更加化妝,主要是為了更快地掃描代碼,但我們在這裡介紹並確保常見的最佳實踐以及代碼質量。如今,Eslint,JSlint和Jshint是最受歡迎的JavaScript Linters。就我個人而言,我曾經經常與Jshint合作,但是Eslint已開始成為我的最愛,這主要是因為它的自定義規則和ES2015早期支持。
>開始伸長時,如果彈出了很多錯誤,請修復它們!在您的襯裡很高興之前,不要繼續其他任何事情!>
更新依賴項>更新依賴項應仔細完成。當不關注依賴性經歷的變化時,很容易引入更多錯誤。一些項目可能與固定版本(例如V1.12.5)一起使用,而另一些項目則使用通配符版本(例如V1.12.x)。如果您需要快速更新,則構建版本號如下:major.minor.patch。如果您不熟悉語義版本的工作方式,我建議您閱讀Tim Oxley的這篇文章。
>
>沒有更新依賴性的一般規則。每個項目都是不同的,應處理。更新依賴的補丁編號根本不應該是問題,而未成年人通常也可以。只有當您碰到主要依賴項的主要數量時,才能查找到底發生了什麼變化。也許API已完全改變,您需要重寫應用程序的大部分。如果這不值得付出努力,我將避免更新到下一個主要版本。
>>如果您的項目使用NPM作為依賴項管理器(並且沒有任何競爭對手),則可以使用CLI的方便的NPM命令檢查任何過時的依賴項。讓我用我的一個名為Frontbook的項目中的一個示例來說明這一點,我經常在其中更新所有依賴項:
>
>讓我們弄髒>我希望您隨身攜帶的主要消息是,清理並不一定意味著刪除和重寫大型代碼。當然,這有時是唯一的解決方案,但它不應該是您的第一步也是唯一的一步。 JavaScript可能是一種奇怪的語言,因此通常不可能提供通用建議。您始終必須評估您的特定情況並找出工作解決方案。
建立單位測試
進行單元測試可確保您了解代碼的工作原理,並且您不會意外地破壞任何內容。 JavaScript單元測試值得自己的文章,因此我將無法在此處詳細介紹。廣泛使用的框架是業力,茉莉,摩卡或Ava。如果您還想測試用戶界面,建議使用Nightwatch.js和Dalekjs瀏覽器自動化工具。
>
單元測試和瀏覽器自動化之間的差異是,前者對您的JavaScript代碼本身進行了測試。它確保您的所有模塊和一般邏輯工作。另一方面,瀏覽器自動化測試項目的表面(用戶界面),確保元素在正確的位置並按預期工作。 在開始重構其他任何內容之前,請先註意單位測試。您的項目的穩定性將有所改善,您甚至沒有考慮到可伸縮性!一個很大的副作用並不是一直擔心您可能會破壞某物並且沒有註意到。>
麗貝卡·墨菲(Rebecca Murphey架構
JavaScript體系結構如果您的項目中沒有任何架構(也許所有內容都在一個巨大的應用程序中),那麼該更改它了。不要一次完成所有操作,而是一件一件。同樣,沒有通用的方法來做事,每個項目設置都不同。文件夾結構在項目之間有所不同,具體取決於大小和復雜性。通常 - 在非常基本的層面上 - 結構被分為第三方庫,模塊,數據和入口點(例如index.js,main.js),其中所有模塊和邏輯都將初始化。
>
這使我進行了模塊化。>模塊化所有內容?
到目前為止,模塊化不是對偉大的JavaScript可伸縮性問題的答案。它增加了開發人員必須熟悉的另一層API。不過,這可能值得麻煩。該原理正在將您的所有功能分解為微小的模塊。通過這樣做,可以更容易解決代碼中的問題並在同一代碼庫中的團隊中工作。每個模塊都應該完全有一個目的和任務。一個模塊不知道您的應用程序的外部邏輯,並且可以在不同的位置和情況下重複使用。
>>您如何將大量緊密連接的邏輯分開一個大功能?讓我們一起做。
這不是很模塊化。一切都緊密連接,並取決於其他碎片。想像一下,這具有更大,更複雜的功能,您將不得不對此進行調試,因為某些事情會破裂。也許API沒有響應,JSON內部發生了一些變化。一場噩夢,不是嗎?
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
好吧,我們現在有三個新模塊。讓我們看看重構的獲取電話。
>
<span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
如果!模塊化還有什麼?
> 正如我已經提到的那樣,在微小模塊中轉動您的代碼庫會添加另一層API。如果您不想要它,但希望使其他開發人員更容易使用代碼,那麼保持功能更大是絕對可以的。您仍然可以將代碼分解為更簡單的部分,並更多地關注可測試的代碼。記錄您的代碼
文檔是一個經過廣泛討論的主題。編程社區倡導記錄所有內容的一部分,而另一個小組認為自我記錄的代碼是必經之路。與生活中的大多數事情一樣,我認為兩者都可以保持代碼可讀和可擴展。將JSDOC用於您的文檔。
JSDOC是JavaScript的API文檔生成器。通常可以作為所有知名編輯和IDE的插件可用。讓我們介紹一個例子:
此功能採用兩個參數,並在對像上迭代,然後返回一個數組。這可能不是一個過於復雜的方法,但是對於沒有編寫代碼的人來說,可能需要一段時間才能弄清楚發生了什麼。此外,該方法的作用並不明顯。讓我們開始記錄:
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
>我沒有觸摸很多代碼本身。僅通過重命名功能並添加了一個簡短但詳細的評論塊,我們就可以提高可讀性。
有一個有組織的提交工作流<span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
重構本身就是一個巨大的任務。為了始終能夠滾動您的更改(如果您打破某些內容並以後只注意),我建議您進行所有更新。重寫方法? git commit(或SVN提交,如果您與SVN合作)。重命名為名稱空間,文件夾還是一些圖像? git提交。你明白了。對於某些人來說,這可能很乏味,但這確實可以幫助您正確清理並井井有條。
>為整個重構工作創建一個新分支。永遠不要在主人上工作!您可能必須進行快速更改或將錯誤修復程序上傳到生產環境中,並且不想部署(可能未經測試的)代碼,直到進行測試和完成。因此,建議始終在另一個分支上工作。>
>如果您需要簡短的更新所有這些工作的工作方式,則GitHub的一個有趣的指南在其版本控制工作流程中。如何不失去理智
除了清理所需的所有技術步驟外,我很少在任何地方看到一個重要的步驟:對以前的開發人員沒有生氣。當然,這並不適用於所有人,但我知道有些人會遇到這種情況。我花了數年的時間才真正理解這一點並克服它。我曾經對以前的開發人員代碼,他們的解決方案以及為什麼一切都如此混亂感到非常生氣。
最終,所有的負面情緒永遠不會讓我帶任何地方。它只會導致您重構超出必要的重構,浪費時間,甚至破壞事情。這只是使您越來越煩人。您可能會花費更多的時間,沒有人會感謝您重寫已經有效的模塊。這是不值得的。做需要的事情,分析情況。每次回到模塊時,您總是可以重構微小的位。
>始終有理由以其方式編寫代碼。也許以前的開發人員沒有足夠的時間來正確地做到這一點,不知道更好或其他。我們都去過那裡。
>將其包裹起來
>讓我們再次瀏覽所有步驟,為您的下一個項目創建一個清單。
- 分析項目
- >將開發人員的帽子放在片刻中,並成為用戶查看它的全部內容。
- 瀏覽代碼庫,並列出使用中的工具。
- 讀取工具的文檔和最佳實踐。
- 進行單元測試,以在更高級別上了解該項目。
- 創建一個基線
- 介紹.editorConfig以保持編碼樣式指南在不同的IDE之間保持一致。
- 使凹痕保持一致;標籤或空格,沒關係。
- 強制執行命名約定。
- 如果尚未存在,請添加諸如Eslint,JSlint或Jshint之類的Linter。
- 更新依賴性,但要明智地做並註意確切的更新。
- 清理
- >使用業力,茉莉花或nightwatch.js。
- 確保體系結構和設計模式是一致的。 >
- >決定是否要將代碼庫分為模塊。每個人都只能有一個目的,並且不知道您的代碼庫邏輯的其餘部分。
- 如果您不想這樣做,請更多地關注可測試的代碼,然後將其分解為更簡單的塊。
- >以平衡的方式記錄您的功能和代碼。 >使用JSDOC為您的JavaScript生成文檔。
- 定期進行,並在重要的更改之後進行。如果有什麼破裂,那麼回去就更容易。 >
- 不要失去理智
- 不要對以前的開發人員生氣;消極情緒只會導致不必要的重構和浪費時間。 >
- >有理由編寫代碼的原因。請記住,我們都去過那裡。
- >我真的希望這篇文章對您有所幫助。讓我知道您是否在任何步驟中掙扎,或者也許有一些我沒有提及的好建議!
- >
經常詢問的問題(常見問題解答)關於編寫可維護的JavaScript
什麼是意大利面代碼,為什麼要避免它?
意大利面代碼是一個用來描述一個複雜而糾結的代碼網絡的術語,難以閱讀,理解和維護。它通常是由於缺乏計劃,不遵循編碼標准或不使用面向對象的編程原則等編程實踐而引起的。這種類型的代碼可能會導致許多問題,包括難以追踪的錯誤,添加新功能的困難以及增加的時間和成本。因此,至關重要的是要避免編寫意大利麵條代碼,而要努力尋求清潔,可維護的代碼。 我如何編寫可維護的JavaScript代碼?>編寫可維護的JavaScript代碼涉及幾種最佳實踐。首先,在開始寫作之前,請務必計劃您的代碼。這包括了解您要解決和設計解決方案的問題。其次,遵循編碼標準和約定。這使您的代碼易於閱讀和理解。第三,使用面向對象的編程原理。這有助於組織您的代碼,並使其更加重複使用。最後,始終記錄您的代碼。這包括編寫評論以解釋您的代碼的作用以及為什麼您做出某些決定。包括不使用嚴格的模式,不要正確聲明變量,使用“ ==”操作員而不是'===',而不是正確處理錯誤。避免這些陷阱可以幫助您編寫更清潔,更可維護的代碼。 >如何將現有的意大利麵條代碼重構為可維護的代碼? >重構意大利麵條代碼到可維護的代碼中涉及幾個步驟。首先,您需要了解現有代碼。這可能涉及閱讀代碼並記錄每個部分的作用。其次,確定可以改進的代碼區域。這可能是重複,複雜的條件邏輯或難以理解的代碼的部分。第三,對代碼進行必要的更改。這可能涉及將復雜的功能分解為較小,更易於管理的功能,刪除重複的代碼或重寫代碼的部分,以使其易於理解。最後,測試您的更改,以確保代碼的功能保持不變。
我可以使用哪些工具來幫助編寫可維護的JavaScript代碼?
>有幾種可用的工具可以幫助您編寫可維護的JavaScript代碼。這些包括諸如ESLINT之類的Linter,可以強制執行編碼標準並突出代碼中的潛在問題。 Visual Studio Code等代碼編輯器也可以通過提供語法突出顯示和自動完成等功能來提供幫助。此外,諸如GIT之類的版本控制系統可以幫助您跟踪代碼的更改,並使與他人合作更容易。
面向對象的編程如何編寫可維護的代碼?面向對象的編程(OOP)是一個編程範式,有助於編寫可維護的代碼。它允許您將代碼組織到對像中,該對象可以包含數據和功能。這使您的代碼更加模塊化和重複使用,因為您可以創建執行特定任務的對象,然後在整個代碼中使用它們。 OOP還可以使您的代碼更易於理解,因為它允許您在代碼中建模現實世界概念。
>評論在維護JavaScript代碼中的重要重要性是多麼重要?
>評論對於維護JavaScript至關重要代碼。它可以幫助其他開發人員(以及您的未來自我)了解代碼的作用以及為什麼做出某些決定。這在復雜的代碼庫中尤其重要,在復雜的代碼庫中,了解代碼的功能可能具有挑戰性。但是,應明智地使用評論。過度註釋會使代碼變得混亂且難以閱讀。理想情況下,您的代碼應該是不言自明的,並保留評論以說明為什麼做出某些決定或澄清代碼的複雜部分。
>>我如何確保我的javascript代碼可擴展?您的JavaScript代碼可擴展,涉及以一種允許其有效處理增加負載的方式設計您的代碼。這可以通過遵循良好的編程實踐,例如使用有效的算法和數據結構,避免全局變量並最大程度地減少DOM操縱。此外,使用模塊化方法的編碼方法,其中您的代碼被分解為較小的可重複使用的零件,也可以增強可擴展性。
>>測試在編寫可維護的JavaScript代碼中的作用是什麼?測試在編寫可維護的JavaScript代碼中起著至關重要的作用。它有助於確保您的代碼能夠按預期工作,並可以在開發過程的早期捕獲錯誤。您可以使用幾種類型的測試,包括單元測試,集成測試和端到端測試。使用這些測試方法的組合可以幫助確保您的代碼堅固且可靠。
>>如何跟上編寫可維護的JavaScript代碼的最新最佳實踐? ,參與在線社區。此外,練習持續學習並定期審查和重構您的代碼也可以幫助您保持最新的最新最佳實踐。
>
以上是解開意大利麵條代碼:編寫可維護的JavaScript的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。
