:從《不好的風格》練習看如何識別并修復代碼風格問題)
文檔教程前端【免費下載鏈接】zh.javascript.info現(xiàn)代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 規(guī)范為基準通過簡單但足夠詳細的內(nèi)容為你講解從基礎(chǔ)到高階的 JavaScript 相關(guān)知識。項目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info點擊查看免費下載本文基于 zh.javascript.info現(xiàn)代 JavaScript 教程代碼質(zhì)量章節(jié)中的實戰(zhàn)練習展開。該練習給出了一段“風格很差但功能正確”的pow冪函數(shù)代碼要求讀者逐行找出風格問題并修復。讀完本文你將能系統(tǒng)地識別函數(shù)簽名空格、花括號位置、運算符兩側(cè)空格、分號缺失、超長行、多變量聲明等常見風格缺陷并掌握一套可直接套用的修復方法文中還會結(jié)合 代碼風格主文 的規(guī)則體系與 ESLint 等自動檢查工具幫助你建立可落地的代碼風格習慣。練習背景它在教程中的位置與考察目標這段練習位于教程的 1-js/03-code-quality/02-coding-style 目錄下是“代碼風格”一章的第一個任務(wù)題目本身存放在 task.md參考答案存放在 solution.md。該章的核心主張非常明確“我們的代碼必須盡可能的清晰和易讀”良好的代碼風格是一項“編程藝術(shù)”——以正確且易于他人閱讀的方式完成復雜任務(wù)。練習的目的正是把這一抽象原則落到具體代碼上題目給出的代碼在語法上完全合法、能正確計算x的n次冪但充斥著大量風格缺陷。學習者需要像“審稿人”一樣逐行挑出問題并給出修復版本。原始代碼一段“能跑但難看”的 pow 函數(shù)練習給出的原始代碼如下這就是 task.md 中待修復的版本function pow(x,n) { let result1; for(let i0;in;i) {result*x;} return result; } let xprompt(x?,), nprompt(n?,) if (n0) { alert(Power ${n} is not supported, please enter an integer number greater than zero); } else { alert(pow(x,n)) }功能上它完成了三件事定義pow(x, n)冪函數(shù)通過兩次prompt獲取x與n當n 0時提示不支持否則彈出計算結(jié)果。但這段代碼在可讀性上有大量問題接下來我們對照 solution.md 中逐條標注的注釋逐一剖析。逐條剖析代碼中的每一處風格缺陷下面是在原始代碼上標注出的全部問題。為了方便對照先看帶注釋的完整版本function pow(x,n) // - 參數(shù)之間沒有空格 { // - 花括號獨占了一行 let result1; // - 號兩邊沒有空格 for(let i0;in;i) {result*x;} // - 沒有空格 // { ... } 里面的內(nèi)容應該在新的一行上 return result; } let xprompt(x?,), nprompt(n?,) // -- 從技術(shù)的角度來看是可以的 // 但是拆分成 2 行會更好并且這里也缺了空格和分號 ; if (n0) // - (n 0) 里面沒有空格并且應該在本行上面加一個空行 { // - 花括號獨占了一行 // 下面的一行代碼太長了可以將其拆分成 2 行以提高可讀性 alert(Power ${n} is not supported, please enter an integer number greater than zero); } else // - 可以像 } else { 這樣寫在一行上 { alert(pow(x,n)) // 缺失了空格和分號 ; }缺陷一函數(shù)簽名中參數(shù)之間沒有空格function pow(x,n)中x與n之間缺少空格。教程的 代碼風格主文 將“空格”視為代碼風格的基礎(chǔ)語法要素并提供了完整的風格備忘圖見下圖其中明確要求函數(shù)名與左括號之間、括號與參數(shù)之間都要有空格參數(shù)之間也要有空格。修復方式function pow(x, n)。缺陷二花括號獨占一行原始代碼把左花括號{放在了單獨一行function pow(x,n) {主文在“花括號”一節(jié)中明確指出在大多數(shù) JavaScript 項目中花括號采用“Egyptian” 風格即 KR 風格—— 左花括號與相應的關(guān)鍵詞位于同一行末尾而不是另起一行且左括號前應有一個空格if (condition) { // do this // ...and that }因此{應緊跟函數(shù)簽名function pow(x, n) {。類似的錯誤在后面的if (n0)與else塊中重復出現(xiàn)屬于同一類問題。缺陷三賦值運算符兩側(cè)沒有空格let result1;中兩側(cè)沒有空格。主文要求“運算符周圍要有空格”這是提高可讀性的基礎(chǔ)規(guī)則。修復為let result 1;。缺陷四for 循環(huán)整體壓縮在一行、缺少空格、代碼塊未換行for(let i0;in;i) {result*x;}同時違反了幾條規(guī)則for關(guān)鍵字與左括號之間沒有空格主文要求for、if、while等關(guān)鍵詞后留空格循環(huán)頭部i0、in、i內(nèi)部以及分號后缺少空格循環(huán)體{result*x;}被壓在同一行。主文明確指出{ ... }里面的內(nèi)容應該在新的一行上。修復為for (let i 0; i n; i) { result * x; }缺陷五用逗號在一行內(nèi)聲明多個變量let xprompt(x?,), nprompt(n?,)在語法上完全合法這也是原注釋所說“從技術(shù)的角度來看是可以的”但把兩次prompt擠在同一行既缺空格、又缺分號可讀性差。拆成兩行、每行一個變量聲明更清晰let x prompt(x?, ); let n prompt(n?, );缺陷六if 條件內(nèi)部沒有空格且上方缺少空行if (n0)中n0內(nèi)部沒有空格應為n 0。同時這段if之前的let聲明與if之間沒有空行。主文在“縮進”一節(jié)中專門講了垂直方向上的縮進用空行把代碼拆分成邏輯塊。即使是一個函數(shù)也應分割為“變量初始化 → 主邏輯 → 返回值”等邏輯塊寫代碼時不應出現(xiàn)連續(xù)超過 9 行都沒有被垂直分割的情況。因此let聲明與if之間應插入一個空行。缺陷七單行過長alert(Power ${n} is not supported, please enter an integer number greater than zero);這一行太長。主文在“行的長度”一節(jié)中指出沒有人喜歡讀一長串代碼最好將代碼分割一下。一行最大長度應由團隊達成一致通常是 80 或 120 個字符。模板字符串反引號天然支持跨行因此可以把這條提示信息拆成兩行alert(Power ${n} is not supported, please enter an integer number greater than zero);主文中還給出了if條件過長時的拆行示范——把多個條件縱向排列每個條件一行if ( id 123 moonPhase Waning Gibbous zodiacSign Libra ) { letTheSorceryBegin(); }缺陷八else 單獨占一行else獨占一行不如寫成} else {。主文在花括號一節(jié)的示例if (condition) { ... }以及風格備忘圖中都體現(xiàn)了這一點閉合花括號與else、下一個左花括號連寫在一行上整體結(jié)構(gòu)更緊湊、塊歸屬一目了然。缺陷九函數(shù)調(diào)用缺少空格與分號alert(pow(x,n))存在兩個問題嵌套調(diào)用pow(x,n)內(nèi)部沒有空格應為pow(x, n)且語句末尾缺少分號。主文在“分號”一節(jié)中強調(diào)每一個語句后面都應該有一個分號即使它可以被跳過——因為在極少數(shù)情況下JavaScript 的換行符不會被解釋為分號容易埋下隱患詳見 分號一節(jié)。修復為alert( pow(x, n) );修復后的完整版本綜合以上所有修正solution.md 給出的參考答案如下function pow(x, n) { let result 1; for (let i 0; i n; i) { result * x; } return result; } let x prompt(x?, ); let n prompt(n?, ); if (n 0) { alert(Power ${n} is not supported, please enter an integer number greater than zero); } else { alert( pow(x, n) ); }對比前后兩個版本可以看到函數(shù)體內(nèi)變量初始化、循環(huán)邏輯、返回值之間用空行做了垂直分割for循環(huán)體獨占一行并縮進兩個空格if/else以} else {形式連接所有運算符、逗號、括號前后都保留了規(guī)范的空格每條語句都以分號結(jié)尾。功能完全不變但可讀性有了質(zhì)的提升。這也是 代碼風格主文 開頭給出的規(guī)范示例風格主文中n 0版本的完整范本可參見該文“語法”一節(jié)。從“改對”到“寫對”支撐這些規(guī)則的原理練習只要求修復一段代碼但真正重要的是理解每條規(guī)則背后的理由。結(jié)合 代碼風格主文可以把本練習涉及的規(guī)則歸納為幾組花括號選擇哪種寫法主文對比了if的四種寫法if (n 0) {alert(...)}—— 初學者常把花括號與語句擠在一行非常不好if (n 0)換行后再寫alert(...)、不加花括號 —— 永遠不要這樣做添加新行很容易出錯if (n 0) alert(...)單行無花括號 —— 如果代碼很短可以接受if (n 0) { ... }——最好的方式。本練習中的if (n0)恰好屬于第 1 類的變形花括號另起一行應改為第 4 類寫法。對于極短語句如if (cond) return null單行寫法也是可接受的但塊結(jié)構(gòu)通常更具可讀性??s進水平與垂直兩個維度水平縮進通常為 2 或 4 個空格或 Tab。如今空格更普遍因為空格可以比 Tab 做出更靈活的縮進配置例如把函數(shù)參數(shù)與左括號對齊。本練習統(tǒng)一采用 2 空格縮進。垂直縮進用空行把代碼拆分成邏輯塊。本練習在result初始化、for循環(huán)、return之間以及l(fā)et聲明與if之間插入空行正是這一原則的體現(xiàn)。嵌套層級盡量淺主文建議盡量避免過深嵌套例如循環(huán)內(nèi)不要層層加if可以用continue提前跳出for (let i 0; i 10; i) { if (!cond) continue; ... // - 沒有額外的嵌套 }if/else與return的組合也可以達到同樣效果把“特殊情況”在一開始就處理掉例如n 0時直接return主代碼流就不需要額外嵌套。本練習的pow函數(shù)雖然嵌套不深但else分支的寫法同樣可以套用這一思路——條件不滿足時立即結(jié)束主體邏輯平鋪展開。函數(shù)位置先調(diào)用、后定義主文指出如果代碼中有“輔助函數(shù)”與調(diào)用它們的代碼組織方式有三種函數(shù)在上、調(diào)用在下調(diào)用在上、函數(shù)在下混合式。大多數(shù)情況下“先寫調(diào)用代碼、再寫函數(shù)”更好因為閱讀時我們首先想知道的是“它做了什么”。本練習中pow先定義后調(diào)用屬于第 1 種方式在課堂練習中完全合理但在真實項目中把“做什么”的調(diào)用代碼放在前面往往更利于他人快速理解程序主干。把規(guī)則自動化風格指南與檢查器Linters人工逐行審查難免遺漏團隊協(xié)作時更需要統(tǒng)一標準。主文介紹了兩類工具化手段風格指南風格指南是“如何編寫代碼”的通用規(guī)則集涵蓋用哪個引號、縮進幾個空格、一行最大長度等細節(jié)。當團隊所有成員遵循同一份指南時無論代碼由誰編寫風格都是統(tǒng)一的。業(yè)界已有多種成熟方案可供選擇如 Google、Airbnb、Idiomatic.JS、StandardJS 等初學者可以從本文這類基礎(chǔ)規(guī)則起步再挑選自己偏好的指南。ESLint 等自動檢查器檢查器Linters可以自動檢查代碼風格并提出改進建議而且順帶能發(fā)現(xiàn)變量或函數(shù)名拼寫錯誤等真實 bug——因此即使不打算固守某種風格也建議安裝一個。主文提到 JSLint、JSHint、ESLint 等工具并給出了 ESLint 的啟用流程安裝 Node.js使用npm install -g eslint安裝 ESLint在項目根目錄創(chuàng)建.eslintrc配置文件在編輯器中安裝/啟用 ESLint 插件。主文給出的.eslintrc示例{ extends: eslint:recommended, env: { browser: true, node: true, es6: true }, rules: { no-console: 0, indent: 2 } }其中extends: eslint:recommended表示基于 ESLint 的推薦規(guī)則集進行設(shè)置然后通過rules覆蓋或追加自定義規(guī)則——例如示例中把縮進規(guī)則設(shè)定為 2 空格indent: 2與本練習采用的縮進風格完全一致。把本練習中發(fā)現(xiàn)的“缺陷類型”空格缺失、分號缺失、花括號位置、行過長等交給檢查器自動把關(guān)正是“從人工修復到機器預防”的最佳實踐路徑。總結(jié)一份可復用的代碼風格自查清單回到本練習把 solution.md 揭示的九類問題整理成清單即可作為日常自查的速查表參數(shù)與括號函數(shù)名與(之間、參數(shù)之間、嵌套調(diào)用參數(shù)之間都要有空格花括號位置左花括號與關(guān)鍵詞同行KR 風格} else {連寫在一行運算符空格、、*等運算符兩側(cè)保留空格控制結(jié)構(gòu)for、if、while后留空格循環(huán)體內(nèi)容換行、縮進變量聲明每行一個變量使用let x ...;完整寫法并加結(jié)尾分號空行分割不同邏輯塊之間用空行做垂直分割行長度超過團隊約定通常 80/120 字符時拆分模板字符串可跨行分號每條語句末尾都寫分號嵌套深度用continue、提前return減少嵌套層級。主文在“總結(jié)”一節(jié)給出的判斷標準值得反復體會當我們思考如何寫“更好”的代碼時應該問自己兩個問題——“什么可以讓代碼可讀性更高、更容易被理解”以及“什么可以幫助我們避免錯誤”本練習的每一處修復最終都服務(wù)于這兩個目標。贊分享文檔教程前端【免費下載鏈接】zh.javascript.info現(xiàn)代 JavaScript 教程The Modern JavaScript Tutorial以最新的 ECMAScript 規(guī)范為基準通過簡單但足夠詳細的內(nèi)容為你講解從基礎(chǔ)到高階的 JavaScript 相關(guān)知識。項目地址https://gitcode.com/gh_mirrors/zh/zh.javascript.info點擊查看免費下載相關(guān)推薦修復 JavaScript 糟糕代碼風格以 pow 函數(shù)練習剖析編碼規(guī)范javascript.info 編碼風格實戰(zhàn)修復 JavaScript 糟糕代碼風格以 pow 函數(shù)練習剖析編碼規(guī)范javascript.info 編碼風格實戰(zhàn) 整潔、易讀的代碼與正確運行的代碼同文檔/教程前端終極idiomatic.js代碼審查寶典快速識別和修復JavaScript代碼風格問題終極idiomatic.js代碼審查寶典快速識別和修復JavaScript代碼風格問題 idiomatic.js是一個專注于編寫一致、地道JavaScript1BRC代碼風格統(tǒng)一代碼風格與格式化規(guī)范1BRC代碼風格統(tǒng)一代碼風格與格式化規(guī)范 概述 在十億行挑戰(zhàn)1BRC這個高性能計算項目中代碼風格的一致性對于項目維護和性能優(yōu)化至關(guān)重要。本文深入探討1B性能測試大數(shù)據(jù)上一篇3分鐘極速部署為華碩路由器打造全網(wǎng)廣告攔截系統(tǒng)下一篇如何安裝 Mac Mouse Fix為 Mac 鼠標選對安裝方式并設(shè)置平滑滾動的完整指南創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考