So schreiben Sie hochwertigen JavaScript-Code

So schreiben Sie hochwertigen JavaScript-Code

Vor einiger Zeit wurde ein Video mit dem Titel „Human High Quality Male“ populär. Ich glaube, viele Studenten haben es gesehen. Heute möchte ich Ihnen also erklären, was „Code in menschlicher Qualität“ ist. Haha, nur ein Scherz.

Tatsächlich teile ich hier ein paar kleine Tricks, die ich in meinem täglichen Leben angewendet habe. Ich hoffe, sie können jedem etwas Inspiration und Hilfe bringen.

Wie schreibe ich hochwertigen JavaScript-Code? Lassen Sie uns gemeinsam den folgenden Artikel studieren

1. Einfach zu lesender Code

Zunächst wird der Code für Sie selbst oder Teammitglieder zum Lesen geschrieben, und eine gute Lesemethode ist eine Voraussetzung für das Schreiben qualitativ hochwertigen Codes. Hier sind vier spezielle Bedienungsmethoden zusammengefasst, die wir mit Ihnen teilen möchten.

1. Einheitliches Codeformat

Schreiben Sie nicht manchmal so und manchmal anders. Versuchen Sie, Ihren Schreibstil konsistent zu halten. Hier ist ein Beispiel.

//schlecht
Funktion foo(x,y) {
  zurückkehren {
    Summe: x + y
  };
}
Funktion bar(m, n){
  sei ret = m*n
  Rückkehr ret;
}
//Gut
function foo(x, y) { // Mit entsprechenden Leerzeichen trennen. Im Allgemeinen werden vor Symbolen keine Leerzeichen eingefügt, nach Symbolen jedoch schon. return {
    Summe: x + y, // Abschließende Kommas sind zulässig und vereinfachen das Hinzufügen oder Entfernen von Elementen aus Objekten und Arrays} // Lassen Sie das schließende Semikolon weg, aber Sie müssen wissen, wie Sie das Risiko vermeiden}
Funktion bar(m, n) {
  sei ret = m * n
  Rückkehr zurück
}


Da es unpraktisch ist, das Codeformat manuell festzulegen, können Sie einige Tools zur automatischen Konvertierung des Formats verwenden, z. B. das Prettier-Plug-in (https://prettier.io/).

2. Entfernen Sie magische Zahlen

magic number ist ein bestimmter numerischer Wert, der bei der Programmierung direkt in den Programmcode geschrieben wird (z. B. „10“, „123“ usw.). Obwohl der Programmierer beim Schreiben des Programms die Bedeutung des Werts verstehen kann, wird es für andere Programmierer oder sogar für den Programmierer selbst nach einer gewissen Zeit schwierig sein, den Zweck des Werts zu verstehen.

//schlecht
setTimeout(blastOff, 86400000)
Dokument.onkeydown = Funktion (ev) {
  wenn (ev.keyCode === 13) {
    // alle
  }
}
//Gut
const MILLISEKUNDEN_IN_A_TAG = 86400000
Konstante ENTER_KEY = 13
setTimeout(blastOff, MILLISEKUNDEN_IN_A_TAG)
Dokument.onkeydown = Funktion (ev) {
  wenn (ev.keyCode === ENTER_KEY) {
    // alle
  }
}


Natürlich werden auch magische Zeichenfolgen auf die gleiche Weise wie oben behandelt. Es wird empfohlen, im obigen Code Unterstriche zum Benennen von Konstanten zu verwenden, und es wird empfohlen, Camel Case zum Benennen anderer Variablen und Funktionen zu verwenden.

Tatsächlich gilt dasselbe Prinzip auch für die Reduzierung der Häufigkeit der Verwendung von this . Wenn der Code mit einer großen Anzahl von this gefüllt ist, ist es für uns oft schwierig zu erkennen, wer es ist, und das Lesen nimmt viel Zeit in Anspruch.

//schlecht
Klasse Foo {
    foo() {
        diese.Zahl = 100
        dies.el.onclick = Funktion () {
            this.className = "aktiv"
        }
    }
}
//Gut
Klasse Foo {
    foo() {
        lass Kontext = dies
        Kontext.Nummer = 100
        Kontext.el.onclick = Funktion () {
            lass el = dies
            el.className = "aktiv"
        }
    }
}

3. Einzelfunktionsprinzip

Egal, ob Sie Module, Klassen oder Funktionen schreiben, sie sollten jeweils eine einzelne Funktion haben und nicht zu viele Dinge tun. Dadurch sind sie sehr leicht zu lesen und sehr flexibel erweiterbar.

//schlecht
Funktion kopieren(Objekt, tief) {
  wenn (tief) {
    //tiefe Kopie} sonst {
    // Oberflächliche Kopie}
}
//Gut
Funktion kopieren(Objekt) {
  // Oberflächliche Kopie}
Funktion deepCopy(Objekt) {
  // tiefe Kopie}

4. Reduzieren Sie die Anzahl der Verschachtelungsebenen

Mehrstufige Verschachtelung, wie etwa bedingte Verschachtelung, Schleifenverschachtelung, Rückrufverschachtelung usw., ist für das Lesen des Codes sehr ungünstig, daher sollte die Verschachtelungsebene so weit wie möglich reduziert werden.

Um das Problem verschachtelter Bedingungen zu lösen, können im Allgemeinen guard clause verwendet werden, um frühzeitig zurückzukehren und so die Verschachtelung zu reduzieren.

//schlecht
Funktion foo() {
  Ergebnis lassen
  wenn (ist tot) {
    Ergebnis = deadAmount()
  } anders {
    wenn (istRet) {
      Ergebnis = retAmount()
    } anders {
      Ergebnis = normaler Betrag()
    }
  }
  Ergebnis zurückgeben
}
//Gut
Funktion foo() {
  wenn (ist tot) {
    returniere deadAmount()
  }
  wenn (istRet) {
    return retAmount()
  }
  return normalAmount()
}

Zusätzlich zu Guard-Anweisungen können bedingte Anweisungen auch mithilfe von Kurzschlussoperationen, bedingten Operatoren usw. umgeschrieben werden.

//schlecht
Funktion foo() {
    wenn (istOk) {
        tun()
    }
    lass benoten
    wenn (istAdmin) {
        Note = 1
    } anders {
        Note = 0
    }
}
//Gut
Funktion foo() {
    isOk && todo() // Kurzschlussoperation let grade = isAdmin ? 1 : 0 // bedingter Operator }

Um das Problem verschachtelter Rückrufe zu lösen, können Sie es im Allgemeinen mit der Methode „ async/await “ neu schreiben.

//schlecht
lass fs = erfordern("fs")
Funktion init() {
  fs.mkdir(root, (err) => {
    fs.mkdir(Pfad.beitreten(root, "öffentlich", "Stylesheets"), (err) => {
      fs.writeFile(
        Pfad.Join(Stamm, "öffentlich", "Stylesheets", "style.css"),
        "",
        Funktion (Fehler) {}
      )
    })
  })
}
init()
//Gut
lass fs = erfordern("fs").versprechen
asynchrone Funktion init() {
  warte auf fs.mkdir(root)
  warte auf fs.mkdir(Pfad.beitreten(root, "public", "stylesheets"))
  warte auf fs.writeFile(Pfad.beitreten(root, "public", "stylesheets", "style.css"), "")
}
init()

Zusätzlich zu den vier oben vorgestellten Vorschlägen gibt es noch viele weitere Punkte, die das Leseerlebnis verbessern können, wie z. B.: effektive Anmerkungen, Vermeidung verschiedener Arten von Vergleichen, Vermeidung umständlicher Grammatik usw.

2. Leistungsstarker Code

Bei der Softwareentwicklung wirkt sich die Leistung des Codes direkt auf die Benutzererfahrung des Produkts aus. Hochwertiger Code muss daher eine hohe Leistung aufweisen. Hier sind vier spezielle Bedienungsmethoden zusammengefasst, die wir mit Ihnen teilen möchten.

Tipp: Um die durchschnittliche Zeit von JavaScript zu testen, können Sie console.time() , das Tool JSBench.Me , das performance usw. verwenden.

1. Optimierungsalgorithmus

Rekursion ist ein gängiger Algorithmus. Im Folgenden wird eine Operation zum „Finden der Fakultät“ beschrieben, die mithilfe von Rekursion implementiert wurde.

//schlecht
Funktion foo(n) {
  wenn (n === 1) {
    Rückgabe 1
  }
  Rückgabewert n * foo(n - 1)
}
foo(100) // Durchschnittliche Zeit: 0,47 ms
//Gut
Funktion foo(n, Ergebnis = 1) {
  wenn (n === 1) {
    Ergebnis zurückgeben
  }
  return foo(n - 1, n * result) // Tail-Call-Optimierung hier}
foo(100) // Durchschnittliche Zeit: 0,09 ms


„Tail Call“ ist ein Optimierungsmechanismus für die Speicherverwaltung, der Stapelrahmen wiederverwenden kann, dh der Rückgabewert einer externen Funktion ist der Rückgabewert einer internen Funktion.

2. Verwenden Sie integrierte Methoden

Viele Funktionen können mithilfe integrierter JavaScript Methoden gelöst werden. Häufig ist die zugrunde liegende Implementierung der integrierten Methoden optimal und die integrierten Methoden können im Voraus im Interpreter ausgeführt werden, sodass die Ausführungseffizienz sehr hoch ist.

Das folgende Beispiel zeigt, wie die zusammengesetzte Array-Form aus Objektattributen und -werten erhalten wird.

//schlecht
lass Daten = {
  Benutzername: "leo",
  Alter: 20,
  Geschlecht: "männlich",
}
let ergebnis = []
für (let attr in data) {
  Ergebnis.push([Attr, Daten[Attr]])
}
console.log(Ergebnis)
//Gut
lass Daten = {
  Benutzername: "leo",
  Alter: 20,
  Geschlecht: "männlich",
}
let result = Objekt.einträge(Daten)
console.log(Ergebnis)

3. Reduzieren Sie die Suchvorgänge in der Bereichskette

Die Scope-Kette ist die Implementierung der Scope-Regel. Durch die Implementierung der Scope-Kette können Variablen innerhalb ihres Scope aufgerufen und Funktionen innerhalb ihres Scope aufgerufen werden. Die Scope-Kette ist eine verknüpfte Liste, auf die nur in eine Richtung zugegriffen werden kann. Jeder Knoten in dieser verknüpften Liste ist das variable Objekt des Ausführungskontexts (das aktive Objekt, wenn der Code ausgeführt wird). Der Kopf der einseitig verknüpften Liste (der erste Knoten, auf den zugegriffen werden kann) ist immer das variable Objekt (aktive Objekt) der aktuell aufgerufenen und ausgeführten Funktion, und das Ende ist immer das global aktive Objekt.

Wenn das Konzept zu kompliziert ist, schauen Sie sich das Bild unten an.

Die Gültigkeitsbereichskette ist 3 (Kopf: Balken) -> 2 (Foo) -> 1 (Ende: global). Wenn Sie also nach Variablen suchen, sollten Sie versuchen, die Erfassung am Kopf abzuschließen, damit Sie Leistung sparen können . Der spezifische Vergleich ist wie folgt.

//schlecht
Funktion foo() {
  $("li").click(function () { // Einmal globale Suche$("li").hide() // Erneut globale Suche$(this).show()
  })
}
//Gut
Funktion foo() {
  let $li = $("li") // Reduziere den Suchbereich von $li unter $li.click(function () {      
    $li.ausblenden()               
    $(diese).zeigen()
  })
}


Dasselbe Prinzip gilt nicht nur für die Reduzierung von Suchvorgängen in der Bereichskette, sondern auch für die Reduzierung von Suchvorgängen in Objekteigenschaft.

//schlecht
Funktion istNull(arg) {
  returniere Object.prototype.toString.call(arg) === "[Objekt Null]"
}
Funktion istFunktion(arg) {
  returniere Object.prototype.toString.call(arg) === "[Objektfunktion]"
}
//Gut
let toString = Objekt.prototype.toString
Funktion istNull(arg) {
  return toString.call(arg) === "[Objekt Null]"
}
Funktion istFunktion(arg) {
  return toString.call(arg) === "[Objektfunktion]"
}

4. Vermeiden Sie die Duplizierung von Code

Manchmal gibt es beim Schreiben eines Programms viel sich wiederholenden Code. Dann ist es am besten, sich wiederholende Vorgänge zu vermeiden. Nehmen wir ein einfaches Beispiel und finden durch eine Schleife die Indexposition des ersten Elements, das die Bedingungen erfüllt.

//schlecht
lass Index = 0
für (sei i = 0, len = li.length; i < len; i++) {
    wenn (li[i].dataset.switch === "on") {
        Index = i
    }
}
//Gut
lass Index = 0
für (sei i = 0, len = li.length; i < len; i++) {
    wenn (li[i].dataset.switch === "on") {
        Index = i
        break // Die folgende Schleife ist sinnlos und führt unnötigen Code aus}
}


Schauen wir uns einen weiteren Fall der Berechnung der „Fibonacci-Folge“ an.

//schlecht
Funktion foo(n) {
  wenn (n < 3) {
    Rückgabe 1
  }
  gibt foo(n - 1) + foo(n - 2) zurück
}
foo(40) // Durchschnittliche Zeit: 1043ms
//Gut
lass cache = {}
Funktion foo(n) {
  wenn (n < 3) {
    Rückgabe 1
  }
  wenn (!cache[n]) {
    Cache[n] = foo(n - 1) + foo(n - 2)
  }
  Cache zurückgeben[n]
}
foo(40) // Durchschnittliche Zeit: 0,16 ms


Dabei werden die Ergebnisse der rekursiven Ausführung in einem Array zwischengespeichert, sodass der nächste wiederholte Code die Daten im Cache direkt lesen kann, was die Leistung erheblich verbessert.

Der mit einem Kreuz markierte Teil wird zwischengespeichert und die Berechnung wird nicht wiederholt.

Zusätzlich zu den vier oben vorgestellten Vorschlägen gibt es viele weitere Punkte, die die Codeleistung verbessern können, z. B.: Reduzierung von DOM-Operationen, Drosselung der Verarbeitung, Ereignisdelegierung usw.

3. Robuster Code

Der sogenannte robuste Code ist der Code, der so geschrieben wird, dass er erweiterbar, wartbar und testbar ist. Hier sind vier spezielle Bedienungsmethoden zusammengefasst, die wir mit Ihnen teilen möchten.

1. Neue Syntax verwenden

Viele neue Syntaxen können die Fehler früherer Syntaxen ausgleichen und den Code robuster und zukunftssicherer machen.

//schlecht
var a = 1
istNaN(NaN) // wahr
isNaN(undefiniert) // wahr
//Gut
sei a = 1
Zahl.isNaN(NaN) // wahr
Number.isNaN(undefiniert) // falsch


Durch die neue Syntax können zudem bisherige Operationen vereinfacht und die Codestruktur übersichtlicher gestaltet werden.

//schlecht
let user = { Name: "James", Alter: 36 }
Funktion foo() {
  let arg = Argumente
  let name = Benutzername
  let age = Benutzer.Alter
}
//Gut
let user = { Name: "James", Alter: 36 }
Funktion foo(...arg) { // Restparameter let { Name, Alter } = Benutzer // Destrukturierungszuweisung }

2. Jederzeit erweiterbar

Da Produktanforderungen immer neuen Änderungen unterworfen sind, werden hohe Anforderungen an die Skalierbarkeit der Software gestellt, robuster Code ist daher Code, der jederzeit angepasst werden kann.

//schlecht
Funktion foo(Tier) {
  if (Tier === "Hund" || Tier === "Katze") {
    // alle
  }
}
Funktionsleiste (Name, Alter) {}
bar("james", 36)
//Gut
Funktion foo(Tier) {
  const animals = ["dog", "cat", "hamster", "turtle"] // Erweiterbarer passender Wert if (animals.includes(animal)) {
    // alle
  }
}
function bar(options) {} // kann jede Parameterleiste erweitern({
  Geschlecht: "männlich",
  Name: "James",
  Alter: 36,
})

3. Nebenwirkungen vermeiden

Wenn eine Funktion ein anderes Verhalten ausführt, als einen Wert anzunehmen und ein Ergebnis zurückzugeben, hat dies einen Nebeneffekt. Nebenwirkungen sind nicht unbedingt schädlich, aber wenn sie in einem Projekt hemmungslos auftreten, ist die Wahrscheinlichkeit von Codefehlern sehr hoch.

Es wird empfohlen, globale Variablen oder veränderbare Objekte nicht zu ändern und Anforderungen über Parameter und return zu erfüllen. Durch die Vereinfachung der Funktion lässt sich der Code auch leichter testen.

//schlecht
let fruits = "Apfel Banane"
Funktion splitFruits() {
  Früchte = Früchte.geteilt(" ")
}
Funktion addItemToCart(Warenkorb, Artikel) {
  cart.push({ Artikel, Daten: Datum.jetzt() })
}
//Gut
let fruits = "Apfel Banane"
Funktion splitFruits(Früchte) {    
  returniere Früchte.split(" ")
}
Funktion addItemToCart(Warenkorb, Artikel) {
  return [...Warenkorb, { Artikel, Daten: Date.now() }]
}

4. Logische Bedenken integrieren

Bei zu komplexen Projekten kommt es häufig vor, dass verschiedene Logiken vermischt werden, was für spätere Erweiterungen sehr ungünstig ist und zudem das Verständnis des Codes beeinträchtigt. Versuchen Sie daher, die zugehörige Logik gemeinsam zu extrahieren und zentral zu verwalten. Wie hooks in React und Composition API in Vue3 übernehmen sie alle diese Idee.

//schlecht
Standard exportieren {
  Name: "App",
  Daten(){
    zurückkehren {
      SucheHot: [],
      SucheVorschlag: [],
      Suchverlauf: [],
    },
    montiert() {
      // alles Wichtige
      
      // Aufgabenverlauf
    },
    Methoden: {
      handleSearchSuggest(){
        // todo vorschlagen
      },
      handleSearchHistory(){
        // Aufgabenverlauf
      }
    }
  }
}
//Gut
Standard exportieren {
  Name: "App",
  aufstellen() {
    let { searchHot } = useSearchHot()
    let { searchSuggest, handleSearchSuggest } = useSearchSuggest()
    let { Suchhistorie, Suchhistorie handhaben } = Suchhistorie verwenden()
    zurückkehren {
      SucheHeiß,
      SucheVorschlagen,
      Suchverlauf,
      handleSearchSuggest,
      Suchverlauf behandeln,
    }
  }
}
Funktion useSearchHot() {
  // alles Wichtige
}
Funktion useSearchSuggest() {
  // todo vorschlagen
}
Funktion useSearchHistory() {
  // Aufgabenverlauf
}


Zusätzlich zu den vier oben vorgestellten Vorschlägen gibt es viele weitere Punkte, die die Robustheit des Codes verbessern können, z. B.: Ausnahmebehandlung, Komponententests, Verwendung von TS anstelle von JS usw.

Lassen Sie uns abschließend zusammenfassen, wie Sie hochwertigen JavaScript Code schreiben:


Dies ist das Ende dieses Artikels zum Schreiben von hochwertigem JavaScript-Code. Weitere relevante Inhalte zum Schreiben von hochwertigem JavaScript-Code finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die verwandten Artikel weiter unten. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • 12 Möglichkeiten, hochwertigen JS-Code zu schreiben
  • Die Grundlagen zum Schreiben von qualitativ hochwertigem JavaScript-Code
  • So schreiben Sie hochwertigen JS-Code (Fortsetzung)
  • So schreiben Sie hochwertigen JS-Code
  • Vertiefendes Verständnis von JavaScript-Lernnotizen (I) Schreiben von qualitativ hochwertigem Code
  • Tiefes Verständnis der JavaScript-Serie (1) Die Grundlagen zum Schreiben von qualitativ hochwertigem JavaScript-Code

<<:  Führen Sie Datenstatistiken für verschiedene Werte desselben Felds in SQL durch

>>:  Beispiel für den Aufbau eines Jenkins-Dienstes mit Docker

Artikel empfehlen

Schritte zum Erstellen eines CentOS-Containers über Docker

Inhaltsverzeichnis Vorwort Erstellen Sie ein Brüc...

So erstellen Sie Ihren eigenen nativen JavaScript-Router

Inhaltsverzeichnis Vorwort Einführung JavaScript ...

Lösungen für Probleme bei der Verwendung von addRoutes in Vue-Projekten

Inhaltsverzeichnis Vorwort 1. 404 Seite 1. Ursach...

Die Vollversion des gängigen Linux-Tools vi/vim

Warum Vim lernen? Linux verfügt über eine große A...

Detaillierte Erklärung zum Bereitstellen von H5-Spielen auf einem Nginx-Server

Auf dem Weg zur selbstlernenden Spieleentwicklung...

So zeigen Sie den Nginx-Konfigurationsdateipfad und den Ressourcendateipfad an

Zeigen Sie den Pfad der Nginx-Konfigurationsdatei...

js realisiert das dynamische Laden von Daten durch Wasserfallfluss

In diesem Artikel erfahren Sie den spezifischen C...

Einführung in den Aufbau von NFS-Diensten unter Centos7

Inhaltsverzeichnis 1. Server 2. Kunde 3. Testdien...

Detaillierte Erläuterung der Vue-Projektverpackung

Inhaltsverzeichnis 1. Zugehörige Konfiguration Fa...

Weitere Features der JavaScript-Konsole

Inhaltsverzeichnis Überblick console.log konsole....

Detaillierte Schritte zum Bereitstellen eines Tomcat-Servers basierend auf IDEA

Inhaltsverzeichnis Einführung Schritt 1 Schritt 2...

Lösung für das Problem ungenauer JS-Zahlen

Die verständlichste Erklärung des Genauigkeitspro...