Zum Hauptinhalt springen




Das Schreiben von sauberem Code ist das, was Sie wissen und tun müssen, um sich selbst als professioneller Entwickler zu bezeichnen. Es gibt keine vernünftige Entschuldigung dafür, weniger als das Beste zu tun, was Sie tun können.

En esta publicación del Blog schoolofJavaScript.com, cubriremos los principios generales de codificación limpia para nombrar y usar variables y funciones, así como algunas de las mejores prácticas de codificación limpia específicas de JavaScript.

Was bedeutet saubere Codierung?

Saubere Codierung bedeutet, dass Sie zuerst Code schreiben, um ihn später zu überprüfen, und für Ihre Mitarbeiter, und nicht für die Maschine.

Sie wissen, dass Sie an sauberem Code arbeiten, wenn sich herausstellt, dass jede Routine, die Sie lesen, so ziemlich das ist, was Sie erwartet haben.

Best Practices für sauberen JavaScript-Code

Nachdem wir nun wissen, was jeder Entwickler anstreben sollte, werfen wir einen Blick auf die Best Practices!

Wie soll ich meine Variablen benennen?

Verwenden Sie Namen, die Absichten offenbaren, und machen Sie sich keine Sorgen, wenn Sie lange Variablennamen haben, anstatt einige Tastenanschläge zu speichern.

Wenn Sie dieser Praxis folgen, können Sie nach Ihren Namen suchen, was sehr hilfreich ist, wenn Sie Refactors durchführen oder einfach nur nach etwas suchen.

// Versuche dies zu vermeiden let d; lass dpfg; // Stattdessen kannst du dies tun let days_para_la_deliverga; lass number1;

Nehmen Sie außerdem wichtige Unterscheidungen vor und fügen Sie Variablennamen, wie z. B. deren Typ (ungarische Notation), keine zusätzlichen und unnötigen Namen hinzu.

// versuche dies zu vermeiden let stringname; lassen Sie die Benutzer; // Ändere es besser, also lass name; lassen Sie Benutzer;

Machen Sie die Variablennamen einfach auszusprechen, da der menschliche Verstand weniger Aufwand benötigt, um sie zu verarbeiten.

Wenn Sie mit Ihren Mitentwicklern Codeüberprüfungen durchführen, ist es einfacher, auf diese Namen zu verweisen.

// vermeide dies let let pName, sName; lass cntr; let full = false; if (size> 100) {full = true} // ändere es in let letName, secondName; Zähler lassen; const Max_Size = 100 // ... const isFull = size> Max_Size

Kurz gesagt, verursachen Sie keine zusätzliche Mind Mapping mit ihren Namen.

Wie soll ich meine Funktionen schreiben?

Ihre Funktionen sollten nur eines auf Abstraktionsebene tun.

// Vermeiden Sie diese Funktion Get_User_Route_Manager (req, res) {const {userId} = req.params // SQL-Abfrage online knex ('user') .where ({id: userId}). first () .then ((user) ) => res.json (user))} // versuche const nametable zu machen = 'user' const User = {getOne (userId) {return knex (tableName) .where ({id: nametable}). first ()} } // Routenmanager (z. B. Server / Routen / Benutzer / get.js) Funktion Get_User_Routes_Handler (req, res) {const {userId} = req.params User.getOne (userId) .then ((user) => res. json (Benutzer))}

Nachdem Sie Ihre Funktionen korrekt geschrieben haben, können Sie testen, wie gut Sie mit dem CPU-Profil umgegangen sind, um Engpässe zu finden.

Verwenden Sie lange, beschreibende Namen

Ein Funktionsname muss ein Verb oder eine Verbalphrase sein und seine Absicht sowie die Reihenfolge und Absicht der Argumente mitteilen.

Ein langer, beschreibender Name ist viel besser als ein kurzer, rätselhafter Name oder ein langer, beschreibender Kommentar.

// vermeide das / ** * lade einen neuen Benutzer mit seiner E-Mail-Adresse ein * @param {String} E-Mail-Adresse des Benutzers * / function inv (user) {/ * Implementierung * /} // versuche diese Funktion zu laden invuUser (emailaddress) {/ * Implementierung * /}

Vermeiden Sie die lange Liste der Argumente

Utiliza un único parámetro de objeto y la asignación de desestructuración en su lugar. También hace que el manejo de parámetros opcionales Sein mucho más fácil.

// Versuche die Funktion UserManagement auszuführen (Felder, include, fromDate, toDate) {/ * Implementierung * /} UserManagement (['Vorname', 'Zweiter Name', 'E-Mail'], ['Einladung Benutzer'], '2016-06- 26 ',' 2016-12-18 ') // Versuchen Sie stattdessen, diese Funktion UserManagement ({Felder, Include, FromDate, ToDate}) {/ * Implementierung * /} UserRegister ({Felder: [' Vorname ',' Nachname ' ',' email '], include: [' einladende Benutzer '], fromDate:' 2016-06-26 ', toDate:' 2016-12-18 '})

Nebenwirkungen reduzieren.

Verwenden Sie reine Funktionen ohne Nebenwirkungen, wann immer Sie können. Sie sind wirklich einfach zu bedienen und zu testen.

// versuche diese Funktion nicht auszuführen addItemToCart (Warenkorb, Artikel, Menge = 1) {constreadyInCart = cart.get (item.id) || 0 cart.set (item.id ,readyInCart + Quantity) return cart} // mache dies // ohne die ursprüngliche Kartenfunktion zu ändern addItemToCart (cart, item, Quantity = 1) {const cartCopy = new Map (cart) const againInCart = cartCopy.get (item.id) || 0 cartCopy.set (item.id, bereitsInCart + Menge) return cartCopy} // oder Umkehren der Methodenposition // Sie können erwarten, dass das ursprüngliche Objekt mutiert wird // addItemToCart (Warenkorb, Artikel, Menge) -> cart. AddItem (Artikel, Menge) const cart = new Map () Object.assign (cart, {addItem (Artikel, Menge = 1) {constreadyInCart = this.get (item.id) || 0 this.set (item.id, bereitsInCart + Menge) Rückgabe}})

Organisieren Sie Ihre Funktionen in einer Datei gemäß der Downgrade-Regel
Las funciones de nivel superior deben estar en los niveles superior e inferior a continuación. Hace que sea natural leer el Quellcode.

// vermeide dies // "Ich brauche einen super langen Namen" -Funktion getFullName (Benutzer) {return `$ {user.firstName} $ {user.lastName}`} Funktion renderEmailTemplate (Benutzer) {// "oder diese" const fullName = getFullName (Benutzer) return 'Lieber $ {fullName}, ...'} // Versuche diese Funktion auszuführen renderEmailTemplate (Benutzer) {// "Ich brauche den vollständigen Namen des Benutzers" const fullName = getFullName (Benutzer) return 'Lieber $ {fullName}, ...'} // Funktion "Ich verwende dies für das Rendern von E-Mail-Vorlagen" getFullName (Benutzer) {return `$ {user.firstName} $ {user.lastName}`}

Beratung oder Änderung

Funktionen müssen etwas tun (ändern) oder etwas beantworten (abfragen), aber nicht beides.

Jeder schreibt gerne JavaScript anders, was tun?
Dado que JavaScript es dinámico y está escrito de forma flexible, es especialmente propenso a errores de Programmierung.

Verwenden Sie die Geschäftsregeln und den Formatierungsstil des Unternehmens.

Je strenger die Regeln sind, desto weniger Aufwand besteht darin, bei Codeüberprüfungen auf das falsche Format hinzuweisen. Es sollte Dinge wie konsistente Namen, Einrückungsgröße, Leerraumplatzierung und sogar Semikolons abdecken.
Für den Anfang ist der Standard-JS-Stil ziemlich gut, aber meiner Meinung nach nicht streng genug. Ich kann den meisten Regeln im Airbnb-Stil zustimmen.

Wie schreibe ich schönen asynchronen Code?

Nutze die Versprechen, wann immer du kannst.

Versprechen sind von Knoten 4 aus nativ verfügbar. Anstatt verschachtelte Rückrufe zu schreiben, können Sie realisierbare Versprechen-Anrufe tätigen.

// Vermeiden Sie asyncFunc1 ((err, result1) => {asyncFunc2 (result1, (err, result2) => {asyncFunc3 (result2, (err, result3) => {console.lor (result3)})})}) / / verwendet asyncFuncPromise1 () .then (asyncFuncPromise2) .then (asyncFuncPromise3) .then ((Ergebnis) => console.log (Ergebnis)) .catch ((err) => console.error (err))

La mayoría de las bibliotecas tienen interfaces de devolución de llamada y promesa, y prefieren la última. Incluso puede convertir las API de devolución de llamada para prometer una basada envolviéndolas con paquetes como es6-promisify .

// Vermeiden Sie die Funktion const fs = require ('fs') readJSON (filePath, callback) {fs.readFile (filePath, (err, data) => {if (err) {return callback (err)} try {callback (null) , JSON.parse (Daten))} catch (ex) {Rückruf (ex)}})} readJSON ('./ package.json', (err, pkg) => {console.log (err, pkg)}) // benutze const fs = require ('fs') const promisify = require ('es6-promisify') const readFile = promisify (fs.readFile) Funktion readJSON (filePath) {return readFile (filePath) .then ((data) = > JSON.parse (Daten))} readJSON ('./ package.json') .then ((pkg) => console.log (pkg)) .catch ((err) => console.error (err)) The Der nächste Schritt wäre die Verwendung von Async / Warten (≥ Knoten 7) oder Generatorscon Co (≥ Knoten 4), um synchrone Steuerungsflüsse für Ihren asynchronen Code zu erzielen. const request = require ('request-versprechen-native') Funktion getExtractFromWikipedia (Titel) {Rückgabeanforderung ({uri: 'https://en.wikipedia.org/w/api.php', qs: {title: title, Aktion: 'Abfrage', Format: 'json', Requisite: 'Auszüge', Exintro: wahr, EXPLAINTExt: wahr}, Methode: 'GET', json: wahr}) .then ((body) => Object.keys ( body.query.pages) .map ((key) => body.query.pages [key] .extract)) .then ((extrahiert) => extrahiert [0]) .catch ((err) => {console. error ('getExtractFromWikipedia () error:', err) throw err})} // oder verwende die asynchrone Funktion getExtractFromWikipedia (title) {lass body try {body = warte auf Anfrage ({/ * gleiche Parameter wie oben * /})} catch (err) {console.error ('getExtractFromWikipedia () error:', err) throw err} const extracts = Object.keys (body.query.pages) .map ((key) => body.query.pages [key] .extract) gibt Auszüge zurück [0]} // oder Sie können verwenden: const co = require ('co') const getExtractFromWikipedia = co.wrap (Funktion * (Titel) {Lassen Sie body versuchen {body = Ertragsanforderung ({/ * gleiche Parameter wie oben * /})} catch (err) {console.error ('getExtractFromWikipedia () error:', err) throw err} const extracts = Object.keys (body.query.pages) .map ((key) => body. query.pages [key] .extract) gibt Auszüge zurück [0]}) getExtractFromWikipedia ('Robert Cecil Martin') .then ((robert) => console.log (robert))

Wie soll ich performanten Code schreiben?

Sie müssen zuerst sauberen Code schreiben und dann das Profil verwenden, um Leistungsengpässe zu finden.

Versuchen Sie niemals, zuerst intelligenten Code und Leistungscode zu schreiben, sondern optimieren Sie den Code bei Bedarf und beziehen Sie sich auf die tatsächlichen Auswirkungen anstelle von Mikro-Benchmarks.

Es gibt jedoch einige einfache Szenarien, z. B. das eifrige Initialisieren Ihrer Möglichkeiten (z. B. Joi-Schemas in Routenhandlern, die bei jeder Anforderung verwendet werden und bei jeder Neuerstellung zusätzlichen Aufwand verursachen) und die Verwendung von asynchronem Code anstelle eines Sperrcodes.