Entdecke, was für die Skriptsprache JavaScript seit ECMAScript 6 Neues und Wichtiges hinzukam – mit einem einzigen, umfassenden Tutorial!
Das erwartet dich in diesem JavaScript ES6-Kurs.
JavaScript gibt es schon seit vielen Jahren in Browsern. So gut wie jede Webseite beinhaltet mal mehr mal weniger JS-Code. Obwohl die ersten Versionen noch sehr holprig waren, ließ sich bisher mit dem Standard ES5 ganz gut arbeiten, zumindest wenn man die Fallstricke und Unwägbarkeiten geschickt umschiffen konnte. Warum also etwas Neues lernen und nicht beim Bewährten bleiben? In dieser Lektion zeige ich die Vorteile des neuen Standards ES6 und die Gründe, warum man eigentlich nicht auf diesen verzichten kann.
Diese Lektion stellt eine Möglichkeit vor, eine Entwicklungsumgebung einzurichten. Dabei verwenden wir als IDE Visual Studio Code von MS und ViteJS als Dev-Server.
Bis einschließlich ES5 war das Keyword var die einzige Möglichkeit, Variablen zu deklarieren, und sorgte mit seinen Eigenheiten oft für ungewolltes Verhalten oder sogar Fehler. ES6 schickt die zwei neuen Keywords let und const ins Rennen, die einige Unzulänglichkeiten von var ausbügeln.
Die For-Schleife kennt jeder Webentwickler. Sie wird auch oft für das Durchlaufen von Arrays verwendet. Mit ES6 gibt es eine Variante der For-Schleife, die dies wesentlich kürzer und kompakter erlaubt.
Funktionen sind in JS essenziell und wurden bisher nur über das Keyword function deklariert und definiert. ES6 führt eine sehr elegante und kurze Schreibweise ein, die den Code nicht nur lesbarer macht, sondern auch eine Lösung für ein leidiges Problem mit this bietet.
Optionale Parameter lassen sich in ES5 etwas umständlich realisieren und offenbaren sich dem Aufrufer einer Funktion nicht. Mit ES6 können optionale Parameter mit ihren Standardwerten direkt in die Funktionssignatur geschrieben werden.
Das Destructuring erlaubt das gezielte Extrahieren von Elementen aus Objekten und Arrays. Bei genauem Hinsehen ergeben sich viele Anwendungsmöglichkeiten, die JS-Code eleganter und kompakter machen.
Das Hantieren mit der arguments-Variable war bis ES6 nötig, um eine variable Anzahl an Parametern bei Funktionen zu erlauben. Dies ist in ES6 viel einfacher mit den sogenannten Rest-Parametern möglich.
Nicht nur bei Funktionsdefinitionen kommt der …-Operator bei Rest-Parametern zum Zuge, auch beim Array-Destructuring lässt er sich verwenden, um eben den „Rest“ der Elemente aufzufangen und als Array zur Verfügung zu stellen.
Nicht nur bei Arrays lässt sich der Rest-Operator verwenden, auch bei Objekten kann er die restlichen Properties auffangen und als Objekt zur Verfügung stellen.
Das Gegenteil vom Rest-Operator ist der Spread-Operator. Er sieht genauso aus (…), steht aber auf der anderen Seite einer Zuweisung und breitet das Array in seine Einzelteile aus.
Der „Trick“ mit dem Spread-Operator funktioniert auch bei Objekten sehr gut. Damit lassen sich Objekte in andere Objekte „hineinmischen“. Mit Object.assign() gibt es hierfür allerdings auch eine sehr gute Alternative.
Funktionen in Objektliteralen sind sehr sperrig zu schreiben mit dem function-Keyword. Mit ES6 lassen sie sich aber auch viel kürzer und eingängiger schreiben.
Mit Zeichenketten zu hantieren, gehört zum Basiswerkzeug eines jeden Programmierers. Gut, dass ES6 einige neue und sehr nützliche String-Funktionen bietet, die einiges an Schreibarbeit sparen.
Man kann es nicht anders sagen: Mehrzeilige String-Literale mit integrierten Variablenwerten waren bis ES6 eine Qual und auch sehr unangenehm zu lesen. Die neuen Template-Literale von ES6 sind dagegen eine syntaktische Wohltat.
Schon mit ES5 gibt es einige sehr nützliche Array-Funktionen, die einen mehr funktionalen Ansatz verfolgen. ES6 hat diesen noch ein paar andere hinzugefügt, die den Umgang mit Arrays noch angenehmer machen. Einige der „alten“, schon in ES5 vorhandenen Funktionen werden hier aber auch gewürdigt.
Objekte ließen sich schon immer als ein Key-Value-Store oder Dictionary missbrauchen, allerdings mit einigen Nachteilen. Die neue Map-Datenstruktur entledigt sich dieser Nachteile und bietet solide Wörterbuch-Funktionalität, wie man es aus anderen Programmiersprachen kennt.
Asynchrone Vorgänge können mit Callback-Funktionen behandelt werden, jedoch besteht dabei die Gefahr, dass die Verschachtelungstiefe zu groß und der Code dann unübersichtlich wird (die sogenannte Callback-Hell). Promises beheben dieses Problem, indem sie tiefe Verschachtelungen umgehen und eine Verkettung von asynchronen Vorgängen auf einer Ebene erlauben.
Nachdem mit Promises die Callback-Hell vermieden werden kann, legt das async/await-Konstrukt noch eine Schippe drauf beim syntaktischen Zucker. Es baut auf Promises auf und erlaubt es, asynchrone Vorgänge fast wie synchrone zu programmieren. Wer einmal mit async/await programmiert hat, meidet fortan die direkte Verwendung der then-Methode von Promises (und erst recht die Verwendung von Callbacks).
In Node.js werden Module schon von Anfang an verwendet, jedoch setzte es zu Anfang ausschließlich auf das CommonJS-Modulformat mit require. Seit ES6 gibt es eine Moduldefinition im Standard und damit die neuen Keywords import/export. Mittlerweile wird dieses Format bei fast allen (neuen) JS-Bibliotheken unterstützt, und auch Node.js kann damit in den neuesten Versionen umgehen.
Neben dem statischen Importieren von Modulen mit dem Keyword import, unterstützt ES6 auch das dynamische Importieren mit der import-Funktion. Da das Ganze asynchron funktioniert, wird ein Promise zurückgeliefert, auf dessen Auflösung man vorzüglich mithilfe von await warten kann. Damit steht dem Nachladen von Modulen während der Laufzeit zu beliebigen Zeitpunkten nichts mehr im Weg.
Das klassische objektorientierte Programmieren mit Klassen und Vererbung gab es bis zu ES6 nur über den Umweg eines Prototyps bei einer Konstruktor-Funktion. Das war umständlich, wirkte wenig kompakt und war deswegen auch fehleranfällig. Das neue Keyword class erlaubt nun mit ES6 die Definition in kompakter Form, so wie man es von anderen Programmiersprachen wie Java, C# und C++ kennt. Intern bleibt es aber ein grundlegend prototypenbasiertes System, nur mit schönerer Syntax.
Auch die Vererbung basiert weiterhin auf Prototypen, schreibt sich in ES6 mit dem Keyword extends allerdings wesentlich einfacher und übersichtlicher. Wenn man es verwendet, muss man den Konstruktor der Basisklasse zum richtigen Zeitpunkt mit super aufrufen. Wie das geht, wird in dieser Lektion natürlich auch erklärt.
Auch die Deklaration von Membern bzw. Feldern wurde mit den neueren Standards ermöglicht. Damit lassen sich auch statische Felder deklarieren und initialisieren.
Auch private Felder lassen sich nun deklarieren, und an die kommt man auch garantiert nicht von außen heran. Ein wenig gewöhnungsbedürftig ist die Deklaration, die sich von anderen Programmiersprachen doch merklich unterscheidet.
Mit dem neuen Keyword class und den zusammenhängenden Features wie Vererbung und Datenkapselung (private Felder) müssten doch eigentlich alle OO-Programmierer zufrieden sein, oder? Ich möchte in dieser Lektion eine Alternative für das Erstellen von Objekten vorstellen, die ganz ohne Klassen, Prototypen und this auskommt, dafür aber eine flexiblere Art der „Vererbung“ bzw. besser „Komposition“ erlaubt.
Die wichtigsten Features der Version ES6 und neuer sollten nun abgehandelt sein. Es kommen aber immer wieder Neuerungen hinzu. Einige weniger häufig gebrauchte Funktionen wurden noch nicht erwähnt. In dieser Lektion wird erläutert, was noch zu erwarten ist in Zukunft und welche Funktionen in Spezialfällen noch interessant sein könnten.
Kommentiere jetzt „Modernes JavaScript mit ES6–ES13 (JS-Tutorial)“