Ich habe meine ersten Schritte in JavaScript in etwa im Jahr 2000 gemacht. Seitdem hat sich die
Sprache immens weiterentwickelt und sie wird inzwischen auch für Server-seitige Anwendungen wie bei Node.js
oder für Plugins bei Anwendungen wie Atom verwendet.
Da ich vermehrt Anwendungen lediglich mit JavaScript Code umsetze, bin ich auf der Suche nach
einem Programmierstil, der eine einfache Wartbarkeit und am besten auch eine gute Kapselung von
Funktionalitäten ermöglicht.
Diese Seite soll eine Sammlung von Tipps werden, die mir für dieses Ziel hilfreich erscheinen.
Wie ich allerdings objektorientiert mit Javascript programmiere, habe ich auf der Seite
Objektorientiertes Programmieren in Javascript mit functions
zusammengefasst.
Die Tipps sind natürlich nicht auf meinem Mist gewachsen. Im Endeffekt habe ich im Internet gesucht und die Techniken, die mir hilfreich erschienen, auf diese Seite übernommen. Die Quellen trage ich in dieser Liste zusammen:
const
und let
const
Wenn man Konstanten definiert, so sollten sie immer mit const
deklariert und sofort initiiert
werden. Damit kommt es zu Fehlern, wenn sie unabsichtlich überschrieben werden. Außerdem sollten die
Namen von Konstanten lediglich mit Großbuchstaben und Unterstrichen erfolgen. Konstanten gelten
für den Scope (z.B. Funktionsblock) für den sie definiert wurden.
Wie es funktioniert zeigt für mich am besten folgender Funktionsblock, den ich von der Dokumentation
MDN web docs - const
kopiert habe:
// HINWEIS: Konstanten können sowohl mit Klein- als auch Grossbuchstaben deklariert // werden. Üblicherweise verwendet man aber lediglich Grossbuchstaben als Bezeichner für Konstanten. // Definiert my_fav als eine Konstante und weist ihr den Wert 7 zu. const MY_FAV = 7; // Ein Versuch, der Konstanten einen anderen Wert zuzuweisen, ergibt // einen Fehler. MY_FAV = 20; // Schreibt 7 auf die Konsole. console.log("my favorite number is: " + MY_FAV); // Der Versuch, eine existierende Konstante neu zu definieren, // erzeugt einen Fehler const MY_FAV = 20; // Der Name my_fav ist für die obige Konstante reserviert, weshalb // dieses ebenfalls einen Fehler erzeugt. var MY_FAV = 20; // Auch dies ergibt einen Fehler. let MY_FAV = 20; // Man beachte, dass const Deklarationen auf Blöcke begrenzt sind. if (MY_FAV === 7) { // Dies funktioniert und erzeugt eine neue Konstante MY_FAV innerhalb // des aktuellen Blocks. (Es liesse sich auch mit let eine Variable deklarieren.) const MY_FAV = 20; // MY_FAV ist nun 20 console.log("my favorite number is " + MY_FAV); // Diese Variable hingegen wird in den globalen Kontext gehoisted und ergibt einen Fehler var MY_FAV = 20; } // MY_FAV ist immer noch 7 console.log("my favorite number is " + MY_FAV); // Konstanten benötigten einen Initialwert, weshalb hier ein SyntaxError // erzeugt wird. const FOO; // Konstanten können auch Objekte sein. const MY_OBJECT = {"key": "value"}; // Ein Versuch, der Konstanten ein anderes Objekt zuzuweisen, ergibt // einen Fehler. MY_OBJECT = {"OTHER_KEY": "value"}; // Das Objekt selber hingegen ist nicht vor Veränderungen geschützt. // Das folgende Statement wird ohne Probleme ausgeführt. MY_OBJECT.key = "otherValue"; // Verwerde Object.freeze() um ein Objekt unveränderbar zu machen // Das Gleiche gilt für Arrays const MY_ARRAY = []; // Es ist möglich, neue Einträge an das array anzufügen. MY_ARRAY.push("A"); // ["A"] // Jedoch der Versuch, der Konstanten ein anderes Array zuzuweisen, // ergibt einen Fehler. MY_ARRAY = ["B"]
Daraus ergeben sich folgende Vorteile:
let
Mit let
werden Variablen nur für den aktuellen Code-Block definiert. Man sollte daher
alle lokalen Variablen, die nur für die aktuelle Schleife, Funktion oder if-Block in Verwendung sind,
immer mit let
deklarieren und sofort auch einen Wert zuweisen.
Wendet man let
nicht im Rahmen eines Blocks an (also in der ersten Ebene eines Programms), dann
bleibt der Wert der definierten Variable undefined
. Die Variable ist also nicht angelegt.
Lässt man let
weg, so wird die Variable an den globalen Scope angehängt und ist
überall sichtbar.
Verwendet man var
, so ist der Gültigkeitsbereich der Variable die umschließende
Funktion. Der folgende Code, den ich von der Dokumentation
MDN web docs - let
kopiert habe, beschreibt den Unterschied sehr gut.
function varTest() { var x = 31; if (true) { var x = 71; // gleiche Variable! console.log(x); // 71 } console.log(x); // 71 } function letTest() { let x = 31; if (true) { let x = 71; // andere variable console.log(x); // 71 } console.log(x); // 31 }
Die Verwendung von let
führt zu folgenden Vorteilen:
let
nicht unabsichtlich eine globale Variable anlegen, weil damit der Wert der
Variable undefined
bleibt.
let
im selben Block führt zu einem Syntax-Fehler.
Aus anderen Programmiersprachen wie beispielsweise Java kennt man das Konzept, dass
man Methoden überladen kann. Das heißt man hat im Prinzip zwei Methoden des selben Namens, aber mit
unterschiedlichen Parametern.
Im folgenden ein Java-Beispiel:
public void drawLine(int x1, int y1, int x2, int y2, Color color) { //draw line commands } public void drawLine(int x1, int y1, int x2, int y2) { drawLine(x1, y1, x2, y2, Color.BLACK); }
In JavaScript gibt es Probleme, wenn zwei functions im selben Scope gleich benannt werden. In diesem Fall kann man sich aber darüber hinweghelfen, dass man dem letzten Parameter, der Farbe, einen Default-Wert gibt.
function drawLine(x1, y1, x2, y2, color = 'rgb(0, 0, 0)') { //do stuff here }
Somit kann der Wert beim Aufruf weggelassen werden:
drawLine(0, 0, 100, 100); //black line drawLine(0, 0, 100, 100, 'rgb(255,0,0)'); //red line