您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關如何編寫干凈且可擴展的JavaScript代碼,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
JavaScript起源于早期的網絡。 它最初是一種腳本語言,現在已經發展成為支持服務器端執行的完全成熟的編程語言。
現代Web應用程序嚴重依賴JavaScript,尤其是單頁應用程序(SPA)。 借助React,AngularJS和Vue.js等新興框架,Web應用程序主要使用JavaScript構建。
擴展這些應用程序(前端相當于后端)可能相當棘手。使用一個平庸的設置,您最終將遇到限制并迷失在混亂的海洋中。我想分享一些小技巧,幫助你以一種有效的方式編寫干凈的代碼。
我可以建議保持代碼庫整潔和可讀的最重要的事情是按主題分開特定的邏輯塊(通常是函數)。 如果編寫函數,則該函數應默認為僅具有一個用途,并且不應一次執行多項操作。
另外,應該避免引起副作用,這意味著在大多數情況下,不應該更改在函數外部聲明的任何內容。將數據接收到帶有參數的函數中;不應訪問其他所有內容。如果希望從函數中獲取某些內容,請返回新值。
當然,如果這些函數以類似的方式使用或做類似的事情,您可以將多個函數分組到一個模塊(和/或類,如果您愿意)中。例如,如果您有許多不同的計算要做,那么可以將它們分割成可以鏈接的獨立步驟(函數)。
但是,這些函數都可以在一個文件(模塊)中聲明。下面是JavaScript的例子:
function add(a, b) { return a + b } function subtract(a, b) { return a - b } module.exports = { add, subtract } const { add, subtract } = require('./calculations') console.log(subtract(5, add(3, 2))
如果要編寫前端JavaScript,則一定要對最重要的項目使用默認導出,對次要項目使用命名的導出。
聲明函數時,應始終首選多個參數,而不是一個需要對象的參數:
// GOOD function displayUser(firstName, lastName, age) { console.log(`This is ${firstName} ${lastName}. She is ${age} years old.`) } // BAD function displayUser(user) { console.log(`This is ${user.firstName} ${user.lastName}. She is ${user.age} years old.`) }
這背后的原因是,當您查看函數聲明的第一行時,您確切地知道需要傳遞給函數的內容。
盡管函數的大小應該是有限的(只做一項工作),但是函數的大小可能會變大。在函數體中尋找需要傳遞的變量(嵌套在對象中)將花費更多的時間。有時似乎更容易使用整個對象并將其傳遞給函數,但要擴展應用程序,這種設置肯定會有所幫助。
在某種程度上,聲明特定的參數是沒有意義的。對我來說,它超過了四五個函數參數。如果你的函數變得那么大,你應該使用對象參數。
這里的主要原因是參數需要以特定的順序傳遞。如果有可選參數,則需要傳遞undefined
或null
。使用對象參數,您可以簡單地傳遞整個對象,其中順序和未定義的值并不重要。
Destructuring是ES6引入的一個很好的工具。它允許您從對象中獲取特定字段并立即將其分配給變量。您可以將其用于任何類型的對象或模塊。
// EXAMPLE FOR MODULES const { add, subtract } = require('./calculations')
只導入需要在文件中使用的函數,而不是整個模塊,然后從中訪問特定的函數,這是有意義的。類似地,當您確定您確實需要一個對象作為函數參數時,也可以使用Destructuring。這仍將為您提供函數內部所需內容的概述:
function logCountry({name, code, language, currency, population, continent}) { let msg = `The official language of ${name} ` if(code) msg += `(${code}) ` msg += `is ${language}. ${population} inhabitants pay in ${currency}.` if(contintent) msg += ` The country is located in ${continent}` } logCountry({ name: 'Germany', code: 'DE', language 'german', currency: 'Euro', population: '82 Million', }) logCountry({ name: 'China', language 'mandarin', currency: 'Renminbi', population: '1.4 Billion', continent: 'Asia', })
解構的默認值甚至基本函數參數都非常有用。首先,他們給你一個例子,說明你可以傳遞給函數的值其次,您可以指出哪些值是必需的,哪些不是必需的。使用前面的示例,函數的完整設置可能如下所示:
function logCountry({ name = 'United States', code, language = 'English', currency = 'USD', population = '327 Million', continent, }) { let msg = `The official language of ${name} ` if(code) msg += `(${code}) ` msg += `is ${language}. ${population} inhabitants pay in ${currency}.` if(contintent) msg += ` The country is located in ${continent}` } logCountry({ name: 'Germany', code: 'DE', language 'german', currency: 'Euro', population: '82 Million', }) logCountry({ name: 'China', language 'mandarin', currency: 'Renminbi', population: '1.4 Billion', continent: 'Asia', })
顯然,有時您可能不想使用默認值,而是在不傳遞值時拋出錯誤。然而,這往往是一個方便的技巧。
前面的提示讓我們得出一個結論:不要傳遞不需要的數據。在這里,同樣,這可能意味著在設置函數時需要做更多的工作不過,從長遠來看,它肯定會給你一個更可讀的代碼庫。準確地知道在一個特定的地點使用了哪些值是非常有價值的。
我看過大文件—非常大的文件。 實際上,有超過3,000行代碼。 在這些文件中很難找到邏輯塊。
因此,您應該將文件大小限制為一定數量的行。我傾向于將文件保存在100行代碼以下有時,很難分解文件,它們將增長到200-300行,在極少數情況下,最多可達400行。
超過此閾值,文件將變得混亂且難以維護。隨意創建新的模塊和文件夾。您的項目應該看起來像一個森林,由樹(模塊部分)和分支(模塊和模塊文件的組)組成。
相比之下,您的實際文件應該看起來像shire,到處都有一些小山(小凹痕),但所有文件都相對平坦。盡量使縮進水平保持在4以下。
在團隊中工作需要清晰的樣式指南和格式。ESLint提供了一個巨大的規則集,您可以根據需要進行自定義還有eslint--fix,它糾正了一些錯誤,但不是全部。
相反,我建議使用Prettier來格式化代碼。這樣,開發人員就不必擔心代碼格式化,而只需編寫高質量的代碼。外觀將是一致的,格式自動。
理想情況下,應該根據變量的內容為其命名。下面是一些指導原則,可以幫助您聲明有意義的變量名。
功能
函數通常執行某種操作。為了解釋這一點,人類使用動詞——例如轉換或顯示。最好在函數名的開頭使用動詞,例如convertCurrency
或displayUserName
。
數組
它們通常包含一個項目列表;因此,在變量名后面加上s
。例如:
const students = ['Eddie', 'Julia', 'Nathan', 'Theresa']
布爾值
簡單地從“是”或“必須”接近自然語言開始。你可以這樣問,“那個人是老師嗎?”→“是”或“不是”。“類似:
const isTeacher = true // OR false
數組函數
forEach
、map
、reduce
、filter
等都是很好的原生JavaScript函數,可以處理數組并執行一些操作。我看到很多人只是將el
或element
作為參數傳遞給回調函數。雖然這既簡單又快捷,但是您也應該根據它們的值來命名它們。例如:
const cities = ['Berlin', 'San Francisco', 'Tel Aviv', 'Seoul'] cities.forEach(function(city) { ... })
id
通常,您必須跟蹤特定數據集和對象的id
。當id
被嵌套時,簡單地將它保留為id
。在這里,我喜歡在將對象返回到前端之前將MongoDB _id
映射為簡單的id
。當從對象中提取id
時,在前面加上對象的類型。例如:
const studentId = student.id // OR const { id: studentId } = student // destructuring with renaming
該規則的一個例外是模型中的MongoDB引用。在這里,只需在引用模型之后命名該字段。這將在填充引用文檔時保持清晰:
const StudentSchema = new Schema({ teacher: { type: Schema.Types.ObjectId, ref: 'Teacher', required: true, }, name: String, ... })
在可讀性方面,回調是最糟糕的,尤其是在嵌套時承諾是一個很好的改進,但在我看來,async/await
具有最好的可讀性即使對于初學者,或者來自其他語言的人,這也會有很大幫助。但是,要確保你理解它背后的概念,不要漫不經心地到處使用它。
正如我們在技巧1和2中看到的,保持邏輯在正確的位置是可維護性的關鍵同樣,如何導入不同的模塊可以減少文件中的混亂。導入不同模塊時,我遵循一個簡單的結構:
// 3rd party packages import React from 'react' import styled from 'styled-components' // Stores import Store from '~/Store' // reusable components import Button from '~/components/Button' // utility functions import { add, subtract } from '~/utils/calculate' // submodules import Intro from './Intro' import Selector from './Selector'
我在這里使用react組件作為示例,因為有更多類型的導入。你應該能夠適應你的特定用例。
console.log
是調試?-?的一種很好的方法,非常簡單、快速,而且可以完成任務顯然,有更復雜的工具,但我認為每個開發人員仍然在使用它。如果你忘了清理日志,你的主機最終會變得一團糟。然后有一些日志實際上要保存在代碼庫中;例如,警告和錯誤。
為了解決這個問題,出于調試的原因,您仍然可以使用console.log
,但是對于持久的日志,可以使用loglevel
或winston
這樣的庫。另外,您可以使用ESLint警告控制臺語句。這樣你就可以輕松地在全球范圍內尋找控制臺…并刪除這些語句。
遵循這些準則確實幫助我保持代碼庫的干凈和可伸縮性。有什么特別有用的建議嗎在評論中讓我們知道你將在你的編碼工作流程中包括什么,并且請分享你使用的任何其他技巧來幫助代碼結構!
關于如何編寫干凈且可擴展的JavaScript代碼就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。