這篇文章將為大家詳細(xì)講解有關(guān)如何編寫干凈且可擴展的JavaScript代碼,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)建站專注于網(wǎng)站建設(shè)|企業(yè)網(wǎng)站維護|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計與制作經(jīng)驗,為許多企業(yè)提供了網(wǎng)站定制設(shè)計服務(wù),案例作品覆蓋成都柴油發(fā)電機等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身開發(fā)品質(zhì)網(wǎng)站。JavaScript起源于早期的網(wǎng)絡(luò)。 它最初是一種腳本語言,現(xiàn)在已經(jīng)發(fā)展成為支持服務(wù)器端執(zhí)行的完全成熟的編程語言。
現(xiàn)代Web應(yīng)用程序嚴(yán)重依賴JavaScript,尤其是單頁應(yīng)用程序(SPA)。 借助React,AngularJS和Vue.js等新興框架,Web應(yīng)用程序主要使用JavaScript構(gòu)建。
擴展這些應(yīng)用程序(前端相當(dāng)于后端)可能相當(dāng)棘手。使用一個平庸的設(shè)置,您最終將遇到限制并迷失在混亂的海洋中。我想分享一些小技巧,幫助你以一種有效的方式編寫干凈的代碼。
我可以建議保持代碼庫整潔和可讀的最重要的事情是按主題分開特定的邏輯塊(通常是函數(shù))。 如果編寫函數(shù),則該函數(shù)應(yīng)默認(rèn)為僅具有一個用途,并且不應(yīng)一次執(zhí)行多項操作。
另外,應(yīng)該避免引起副作用,這意味著在大多數(shù)情況下,不應(yīng)該更改在函數(shù)外部聲明的任何內(nèi)容。將數(shù)據(jù)接收到帶有參數(shù)的函數(shù)中;不應(yīng)訪問其他所有內(nèi)容。如果希望從函數(shù)中獲取某些內(nèi)容,請返回新值。
當(dāng)然,如果這些函數(shù)以類似的方式使用或做類似的事情,您可以將多個函數(shù)分組到一個模塊(和/或類,如果您愿意)中。例如,如果您有許多不同的計算要做,那么可以將它們分割成可以鏈接的獨立步驟(函數(shù))。
但是,這些函數(shù)都可以在一個文件(模塊)中聲明。下面是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,則一定要對最重要的項目使用默認(rèn)導(dǎo)出,對次要項目使用命名的導(dǎo)出。
聲明函數(shù)時,應(yīng)始終選多個參數(shù),而不是一個需要對象的參數(shù):
// 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.`) }
這背后的原因是,當(dāng)您查看函數(shù)聲明的第一行時,您確切地知道需要傳遞給函數(shù)的內(nèi)容。
盡管函數(shù)的大小應(yīng)該是有限的(只做一項工作),但是函數(shù)的大小可能會變大。在函數(shù)體中尋找需要傳遞的變量(嵌套在對象中)將花費更多的時間。有時似乎更容易使用整個對象并將其傳遞給函數(shù),但要擴展應(yīng)用程序,這種設(shè)置肯定會有所幫助。
在某種程度上,聲明特定的參數(shù)是沒有意義的。對我來說,它超過了四五個函數(shù)參數(shù)。如果你的函數(shù)變得那么大,你應(yīng)該使用對象參數(shù)。
這里的主要原因是參數(shù)需要以特定的順序傳遞。如果有可選參數(shù),則需要傳遞undefined
或null
。使用對象參數(shù),您可以簡單地傳遞整個對象,其中順序和未定義的值并不重要。
Destructuring是ES6引入的一個很好的工具。它允許您從對象中獲取特定字段并立即將其分配給變量。您可以將其用于任何類型的對象或模塊。
// EXAMPLE FOR MODULES const { add, subtract } = require('./calculations')
只導(dǎo)入需要在文件中使用的函數(shù),而不是整個模塊,然后從中訪問特定的函數(shù),這是有意義的。類似地,當(dāng)您確定您確實需要一個對象作為函數(shù)參數(shù)時,也可以使用Destructuring。這仍將為您提供函數(shù)內(nèi)部所需內(nèi)容的概述:
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', })
解構(gòu)的默認(rèn)值甚至基本函數(shù)參數(shù)都非常有用。首先,他們給你一個例子,說明你可以傳遞給函數(shù)的值其次,您可以指出哪些值是必需的,哪些不是必需的。使用前面的示例,函數(shù)的完整設(shè)置可能如下所示:
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', })
顯然,有時您可能不想使用默認(rèn)值,而是在不傳遞值時拋出錯誤。然而,這往往是一個方便的技巧。
前面的提示讓我們得出一個結(jié)論:不要傳遞不需要的數(shù)據(jù)。在這里,同樣,這可能意味著在設(shè)置函數(shù)時需要做更多的工作不過,從長遠(yuǎn)來看,它肯定會給你一個更可讀的代碼庫。準(zhǔn)確地知道在一個特定的地點使用了哪些值是非常有價值的。
我看過大文件—非常大的文件。 實際上,有超過3,000行代碼。 在這些文件中很難找到邏輯塊。
因此,您應(yīng)該將文件大小限制為一定數(shù)量的行。我傾向于將文件保存在100行代碼以下有時,很難分解文件,它們將增長到200-300行,在極少數(shù)情況下,最多可達(dá)400行。
超過此閾值,文件將變得混亂且難以維護。隨意創(chuàng)建新的模塊和文件夾。您的項目應(yīng)該看起來像一個森林,由樹(模塊部分)和分支(模塊和模塊文件的組)組成。
相比之下,您的實際文件應(yīng)該看起來像shire,到處都有一些小山(小凹痕),但所有文件都相對平坦。盡量使縮進水平保持在4以下。
在團隊中工作需要清晰的樣式指南和格式。ESLint提供了一個巨大的規(guī)則集,您可以根據(jù)需要進行自定義還有eslint--fix,它糾正了一些錯誤,但不是全部。
相反,我建議使用Prettier來格式化代碼。這樣,開發(fā)人員就不必?fù)?dān)心代碼格式化,而只需編寫高質(zhì)量的代碼。外觀將是一致的,格式自動。
理想情況下,應(yīng)該根據(jù)變量的內(nèi)容為其命名。下面是一些指導(dǎo)原則,可以幫助您聲明有意義的變量名。
功能
函數(shù)通常執(zhí)行某種操作。為了解釋這一點,人類使用動詞——例如轉(zhuǎn)換或顯示。好在函數(shù)名的開頭使用動詞,例如convertCurrency
或displayUserName
。
數(shù)組
它們通常包含一個項目列表;因此,在變量名后面加上s
。例如:
const students = ['Eddie', 'Julia', 'Nathan', 'Theresa']
布爾值
簡單地從“是”或“必須”接近自然語言開始。你可以這樣問,“那個人是老師嗎?”→“是”或“不是”。“類似:
const isTeacher = true // OR false
數(shù)組函數(shù)
forEach
、map
、reduce
、filter
等都是很好的原生JavaScript函數(shù),可以處理數(shù)組并執(zhí)行一些操作。我看到很多人只是將el
或element
作為參數(shù)傳遞給回調(diào)函數(shù)。雖然這既簡單又快捷,但是您也應(yīng)該根據(jù)它們的值來命名它們。例如:
const cities = ['Berlin', 'San Francisco', 'Tel Aviv', 'Seoul'] cities.forEach(function(city) { ... })
id
通常,您必須跟蹤特定數(shù)據(jù)集和對象的id
。當(dāng)id
被嵌套時,簡單地將它保留為id
。在這里,我喜歡在將對象返回到前端之前將MongoDB _id
映射為簡單的id
。當(dāng)從對象中提取id
時,在前面加上對象的類型。例如:
const studentId = student.id // OR const { id: studentId } = student // destructuring with renaming
該規(guī)則的一個例外是模型中的MongoDB引用。在這里,只需在引用模型之后命名該字段。這將在填充引用文檔時保持清晰:
const StudentSchema = new Schema({ teacher: { type: Schema.Types.ObjectId, ref: 'Teacher', required: true, }, name: String, ... })
在可讀性方面,回調(diào)是最糟糕的,尤其是在嵌套時承諾是一個很好的改進,但在我看來,async/await
具有好的可讀性即使對于初學(xué)者,或者來自其他語言的人,這也會有很大幫助。但是,要確保你理解它背后的概念,不要漫不經(jīng)心地到處使用它。
正如我們在技巧1和2中看到的,保持邏輯在正確的位置是可維護性的關(guān)鍵同樣,如何導(dǎo)入不同的模塊可以減少文件中的混亂。導(dǎo)入不同模塊時,我遵循一個簡單的結(jié)構(gòu):
// 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組件作為示例,因為有更多類型的導(dǎo)入。你應(yīng)該能夠適應(yīng)你的特定用例。
console.log
是調(diào)試?-?的一種很好的方法,非常簡單、快速,而且可以完成任務(wù)顯然,有更復(fù)雜的工具,但我認(rèn)為每個開發(fā)人員仍然在使用它。如果你忘了清理日志,你的主機最終會變得一團糟。然后有一些日志實際上要保存在代碼庫中;例如,警告和錯誤。
為了解決這個問題,出于調(diào)試的原因,您仍然可以使用console.log
,但是對于持久的日志,可以使用loglevel
或winston
這樣的庫。另外,您可以使用ESLint警告控制臺語句。這樣你就可以輕松地在全球范圍內(nèi)尋找控制臺…并刪除這些語句。
遵循這些準(zhǔn)則確實幫助我保持代碼庫的干凈和可伸縮性。有什么特別有用的建議嗎在評論中讓我們知道你將在你的編碼工作流程中包括什么,并且請分享你使用的任何其他技巧來幫助代碼結(jié)構(gòu)!
關(guān)于如何編寫干凈且可擴展的JavaScript代碼就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。