10 JavaScript-Konzepte, die jeder Node.js-Entwickler beherrschen muss

Rahul Mhatre ist Entwickler-Teamleiter bei der Software AG.

Mit JavaScript und der V8-Engine im Kern, einer ereignisgesteuerten Architektur und sofort einsatzbereiter Skalierbarkeit ist Node.js schnell zum De-facto-Standard für die Erstellung von Webanwendungen und SaaS-Produkten geworden. Mit Node.js Frameworks wie Express, Sails und Socket.IO können Benutzer Anwendungen schnell booten und sich nur auf die Geschäftslogik konzentrieren.

Node.js verdankt JavaScript viel für seine enorme Beliebtheit. JavaScript ist eine Multiparadigmensprache, die viele verschiedene Programmierstile unterstützt, einschließlich funktionaler Programmierung, prozeduraler Programmierung und objektorientierter Programmierung. Dadurch kann der Entwickler flexibel sein und die verschiedenen Programmierstile nutzen.

Aber JavaScript kann ein zweischneidiges Schwert sein. Die Multiparadigma-Natur von JavaScript bedeutet, dass fast alles veränderlich ist. Daher können Sie die Wahrscheinlichkeit einer Objekt- und Bereichsmutation beim Schreiben von Node.js-Code nicht beiseite schieben. Da JavaScript keine Tail-Call-Optimierung aufweist (wodurch rekursive Funktionen Stapelrahmen für rekursive Aufrufe wiederverwenden können), ist es gefährlich, die Rekursion für große Iterationen zu verwenden. Zusätzlich zu solchen Fallstricken ist Node.js Single-Threaded, daher ist es für Entwickler unerlässlich, asynchronen Code zu schreiben.

JavaScript kann ein Segen sein, wenn es mit Vorsicht verwendet wird - oder ein Fluch, wenn Sie rücksichtslos sind. Das Befolgen strukturierter Regeln, Entwurfsmuster, Schlüsselkonzepte und Faustregeln hilft Ihnen bei der Auswahl des optimalen Ansatzes für ein Problem. Welche Schlüsselkonzepte sollten Node.js Programmierer verstehen? Im Folgenden werde ich die 10 JavaScript-Konzepte vorstellen, die meiner Meinung nach für das Schreiben von effizientem und skalierbarem Node.js-Code am wichtigsten sind.

In Verbindung stehendes Video: Node.js Tipps und Tricks

In diesem Erklärvideo lernen Sie verschiedene Techniken kennen, mit denen Sie Ihre Erfahrung in der Knotenentwicklung verbessern können.

JavaScript IIFEs: Sofort aufgerufene Funktionsausdrücke

Ein sofort aufgerufener Funktionsausdruck (IIFE) ist eine Funktion, die ausgeführt wird, sobald sie erstellt wird. Es besteht keine Verbindung zu Ereignissen oder zur asynchronen Ausführung. Sie können ein IIFE wie folgt definieren:

(function () {

// deinen ganzen Code hier

// ...

}) ();

Das erste Klammerpaar function(){...}konvertiert den Code in den Klammern in einen Ausdruck. Das zweite Klammerpaar ruft die aus dem Ausdruck resultierende Funktion auf. Ein IIFE kann auch als selbstaufrufende anonyme Funktion beschrieben werden. Die häufigste Verwendung besteht darin, den Umfang einer Variablen zu begrenzen, die über varden Kontext erstellt wurde, oder den Kontext zu kapseln, um Namenskollisionen zu vermeiden.

JavaScript-Schließungen

Ein Abschluss in JavaScript ist eine innere Funktion, die Zugriff auf den Bereich ihrer äußeren Funktion hat, selbst nachdem die äußere Funktion die Kontrolle zurückgegeben hat. Ein Abschluss macht die Variablen der inneren Funktion privat. Ein einfaches Beispiel für einen Verschluss ist unten dargestellt:

var count = (function () {

    var _counter = 0;

    Rückgabefunktion () {return _counter + = 1;}

}) ();

Anzahl();

Anzahl();

Anzahl();

> // der Zähler ist jetzt 3

Der Variablen countwird eine äußere Funktion zugewiesen. Die äußere Funktion wird nur einmal ausgeführt, wodurch der Zähler auf Null gesetzt und eine innere Funktion zurückgegeben wird. Auf die _counterVariable kann nur über die innere Funktion zugegriffen werden, wodurch sie sich wie eine private Variable verhält.

JavaScript-Prototypen

Jede JavaScript-Funktion verfügt über eine Prototyp-Eigenschaft, mit der Eigenschaften und Methoden angehängt werden. Diese Eigenschaft ist nicht aufzählbar. Es ermöglicht dem Entwickler, Methoden oder Elementfunktionen an seine Objekte anzuhängen. JavaScript unterstützt die Vererbung nur über die Prototyp-Eigenschaft. Bei einem geerbten Objekt verweist die Prototyp-Eigenschaft auf das übergeordnete Objekt. Ein üblicher Ansatz zum Anhängen von Methoden an eine Funktion besteht darin, Prototypen wie folgt zu verwenden:

Funktion Rechteck (x, y) {

    this._length = x;

    this._breadth = y;

}}

Rectangle.prototype.getDimensions = function () {

    return {length: this._length, width: this._breadth};

};

Rectangle.prototype.setDimensions = function (len, bred) {

    this._length = len;

    this._breadth = gezüchtet;

};

Private JavaScript-Eigenschaften unter Verwendung von Verschlüssen

Mit JavaScript können Sie private Eigenschaften mithilfe des Unterstrichpräfixes definieren, wie im obigen Beispiel gezeigt. Dies hindert einen Benutzer jedoch nicht daran, direkt auf eine Eigenschaft zuzugreifen oder diese zu ändern, die privat sein soll.

Das Definieren privater Eigenschaften mithilfe von Schließungen hilft Ihnen bei der Lösung dieses Problems. Die Elementfunktionen, die Zugriff auf private Eigenschaften benötigen, sollten im Objekt selbst definiert werden. Sie können private Objekte mithilfe von Schließungen erstellen, wie unten gezeigt:

Funktion Rechteck (_Länge, _Breite) {

     this.getDimensions = function () {

     return {Länge: _Länge, Breite: _Breite};

     };

     this.setDimension = Funktion (len, gezüchtet) {

     _length = len;

    Breite = gezüchtet

    };

}}

JavaScript-Modulmuster

Das Modulmuster ist das am häufigsten verwendete Entwurfsmuster in JavaScript, um lose gekoppelten, gut strukturierten Code zu erzielen. Sie können damit öffentliche und private Zugriffsebenen erstellen. Ein Weg, um ein Modulmuster zu erreichen, ist unten gezeigt:

var Richtung = (Funktion () {

  var _direction = 'vorwärts'

  var changeDirection = Funktion (d) {

          _direction = d;

  }}

  return {setDirection: function (d) {

          changeDirection (d);

          console.log (_direction);

          }}

  };

}) ();

Direction.setDirection ('rückwärts'); // Ausgaben: 'rückwärts'

console.log (Direction._direction);

Das Revealing Module-Muster ähnelt dem Module-Muster, bei dem die Variablen und Methoden, die verfügbar gemacht werden müssen, in einem Objektliteral zurückgegeben werden. Das obige Beispiel kann unter Verwendung des Revealing Module-Musters wie folgt geschrieben werden:

var Richtung = (Funktion () {

  var _direction = 'forward';

  var _privateChangeDirection = Funktion (d) {

_direction = d;

  }}

  Rückkehr {

          setDirection: _privateChangeDirection

  };

}) ();

JavaScript-Heben

JavaScript verschiebt Variablen und Funktionsdeklarationen vor der Codeausführung an den Anfang ihres Gültigkeitsbereichs. Dies nennt man Heben. Unabhängig davon, wo Sie die Deklaration von Funktionen und Variablen in Ihrem Code platzieren, werden sie vom Interpreter an die Spitze ihres Gültigkeitsbereichs verschoben. Dies kann sein oder nicht, wo Sie sie wollen. Wenn nicht, hat Ihr Programm Fehler.

Variablendeklarationen werden verarbeitet, bevor Code ausgeführt wird. Ironischerweise existieren nicht deklarierte Variablen erst, wenn ihnen ein Wert zugewiesen wird. Dies führt dazu, dass alle nicht deklarierten Variablen zu globalen Variablen werden. Obwohl Funktionsdeklarationen angehoben werden, werden Funktionsausdrücke nicht angehoben. JavaScript hat beim Anheben von Variablen und Funktionen eine Prioritätsreihenfolge.

Die Priorität wird unten von höher nach niedriger angegeben:

  • Variablenzuordnung
  • Funktionsdeklaration
  • Variablendeklarationen

Um Fehler zu vermeiden, sollten Sie Ihre Variablen und Funktionen am Anfang jedes Bereichs deklarieren. 

JavaScript-Currying

Currying ist eine Methode, um Funktionen flexibler zu gestalten. Mit einer Curry-Funktion können Sie alle von der Funktion erwarteten Argumente übergeben und das Ergebnis erhalten, oder Sie können nur eine Teilmenge von Argumenten übergeben und eine Funktion zurückerhalten, die auf den Rest der Argumente wartet. Ein einfaches Beispiel für ein Curry ist unten angegeben:

var myFirstCurry = Funktion (Wort) {

  Rückgabefunktion (Benutzer) {

            return [word, ",", user] .join ("");

  };

};

var HelloUser = myFirstCurry ("Hallo");

HelloUser ("Rahul"); // Ausgabe: "Hallo Rahul"

Die ursprüngliche Curry-Funktion kann direkt aufgerufen werden, indem jeder der Parameter in einem separaten Satz von Klammern nacheinander übergeben wird, wie unten gezeigt:

myFirstCurry ("Hey, wassup!") ("Rahul"); // Ausgabe: "Hey, wassup!, Rahul"

JavaScript-Methoden zum Anwenden, Aufrufen und Binden

Es ist zwingend notwendig für jeden JavaScript - Entwickler , den Unterschied zwischen den zu verstehen call, applyund bindMethoden. Die drei Funktionen sind insofern ähnlich, als ihr erstes Argument immer der "this" -Wert oder Kontext ist, dem Sie die Funktion geben möchten, für die Sie die Methode aufrufen.

Von den dreien callist die einfachste. Dies entspricht dem Aufrufen einer Funktion unter Angabe ihres Kontexts. Hier ist ein Beispiel:

var user = {

     Name: "Rahul Mhatre",

     whatIsYourName: function () {

     console.log (this.name);

     }}

};

user.whatIsYourName (); // Ausgabe: "Rahul Mhatre",

var user2 = {

     Name: "Neha Sampat"

};

user.whatIsYourName.call (user2); // Ausgabe: "Neha Sampat"

Beachten Sie, dass dies applyfast das gleiche ist wie call. Der einzige Unterschied besteht darin, dass Sie Argumente als Array und nicht separat übergeben. Arrays lassen sich in JavaScript einfacher bearbeiten und bieten eine größere Anzahl von Möglichkeiten für die Arbeit mit Funktionen. Hier ist ein Beispiel mit applyund call:

var user = {

     grüße: "Hallo!",

     greetUser: function (userName) {

     console.log (this.greet + "" + userName);

     }}

};

var greet1 = {

     greet: "Hola"

};

user.greetUser.call (greet1, "Rahul") // Ausgabe: "Hola Rahul"

user.greetUser.apply (greet1, ["Rahul"]) // Ausgabe: "Hola Rahul"

Mit dieser bindMethode können Sie Argumente an eine Funktion übergeben, ohne sie aufzurufen. Eine neue Funktion wird mit Argumenten zurückgegeben, die vor weiteren Argumenten begrenzt sind. Hier ist ein Beispiel:

var user = {

     grüße: "Hallo!",

     greetUser: function (userName) {

     console.log (this.greet + "" + userName);

}}

};

var greetHola = user.greetUser.bind ({greet: "Hola"});

var greetBonjour = user.greetUser.bind ({greet: "Bonjour"});

greetHola ("Rahul") // Ausgabe: "Hola Rahul"

greetBonjour ("Rahul") // Ausgabe: "Bonjour Rahul"

JavaScript-Memoisierung

Memoization ist eine Optimierungstechnik, die die Funktionsausführung beschleunigt, indem Ergebnisse teurer Operationen gespeichert und die zwischengespeicherten Ergebnisse zurückgegeben werden, wenn derselbe Satz von Eingaben erneut auftritt. JavaScript-Objekte verhalten sich wie assoziative Arrays, sodass die Memoisierung in JavaScript einfach implementiert werden kann. Zum Beispiel können wir eine rekursive Fakultätsfunktion in eine gespeicherte Fakultätsfunktion umwandeln, wie unten gezeigt:

Funktion memoizeFunction (func) {

  var cache = {};

  Rückgabefunktion () {

          var key = Argumente [0];

          if (Cache [Schlüssel]) {

          Cache zurückgeben [Schlüssel];

          }}

          sonst {

          var val = func.apply (dies, Argumente);

          Cache [Schlüssel] = Wert;

          Rückgabewert;

          }}

  };

}}

var fibonacci = memoizeFunction (Funktion (n)

  return (n === 0);

Überladen der JavaScript-Methode

Durch das Überladen von Methoden können mehrere Methoden denselben Namen, aber unterschiedliche Argumente haben. Der Compiler oder Interpreter bestimmt anhand der Anzahl der übergebenen Argumente, welche Funktion aufgerufen werden soll. Das Überladen von Methoden wird in JavaScript nicht direkt unterstützt. Aber Sie können etwas sehr Ähnliches erreichen, wie unten gezeigt:

Funktion overloadMethod (Objekt, Name, Fn) {

     if (! object._overload) {

    object._overload = {};

     }}

     if (! object._overload [name]) {

    object._overload [name] = {};

    }}

     if (! object._overload [name] [fn.length]) {

object._overload [name] [fn.length] = fn;

    }}

     Objekt [Name] = Funktion () {

         if (this._overload [Name] [Argumente.Länge])

         return this._overload [Name] [Argumente.Länge] .apply (dies, Argumente);

     };

Funktion Studenten () {

  overloadMethod (this, "find", function () {

          // Finde einen Schüler mit Namen

  });

overloadMethod (this, "find", function (first, last) {

          // Finde einen Schüler mit Vor- und Nachnamen

  });

}}

var Studenten = neue Studenten ();

Studenten.find (); // Findet alles

Studenten.find ("Rahul"); // Findet Schüler nach Namen

Studenten.find ("Rahul", "Mhatre"); // Findet Benutzer nach Vor- und Nachnamen

Wenn Sie sich mit Node.js auskennen, werden Sie feststellen, dass es viele Möglichkeiten gibt, fast jedes Problem zu lösen. Der richtige Ansatz ist jedoch entscheidend. Ein falscher Ansatz führt zu mehreren Nebenwirkungen wie uneinheitlichen oder fehlerhaften Anwendungen oder Regressionen, die Sie dazu zwingen, die gesamte Logik neu zu schreiben. Auf der anderen Seite wird der richtige Ansatz den Grundstein für eine robuste, effiziente und skalierbare Anwendung legen.

Die 10 in diesem Artikel beschriebenen JavaScript-Konzepte sind Grundlagen, die jeder Node.js-Entwickler kennen sollte. Aber sie sind die Spitze des Eisbergs. JavaScript ist leistungsstark und komplex. Je häufiger Sie es verwenden, desto besser werden Sie verstehen, wie umfangreich JavaScript wirklich ist. Ein besseres Verständnis einer so umfangreichen Sprache hilft Ihnen sicherlich, Fehler zu vermeiden. Machen Sie in der Zwischenzeit die Grundlagen richtig und Sie werden großartige Ergebnisse sehen.

Rahul Mhatre ist Entwickler-Teamleiter bei der Software AG. Zuvor war er technischer Architekt bei Built.io, das von der Software AG übernommen wurde. 

- -

Das New Tech Forum bietet einen Ort, an dem Sie neue Unternehmenstechnologien in beispielloser Tiefe und Breite erkunden und diskutieren können. Die Auswahl ist subjektiv, basierend auf unserer Auswahl der Technologien, die wir für wichtig und für die Leser von größtem Interesse halten. akzeptiert keine Marketingmaterialien zur Veröffentlichung und behält sich das Recht vor, alle eingebrachten Inhalte zu bearbeiten. Senden Sie alle Anfragen an [email protected]