Neue Sprachfeatures im ECMAScript-6-Entwurf – Teil 1

Seite 2: Symbole, Funktionen und Klassen

Inhaltsverzeichnis

Symbole sind ein neuer Datentyp in ECMAScript 6 mit dem es möglich ist, eindeutige Property-Namen zu definieren. Im Unterschied zur bisherigen Verwendung von Zeichenketten sind Kollisionen untereinander ausgeschlossen. Der Zugriff auf die Eigenschaften des Objekts ist nur über die Symbole selbst gestattet. Damit besteht die Option, private Variablen in einem Objekt zu erstellen:

var MyClass = (function() {

var priv = Symbol('priv');

function MyClass() {
this.publ = "öffentlich";
this[priv] = "privat"
}

MyClass.prototype.print = function() {
console.log(this.publ);
console.log(this[priv]);
};

return MyClass;

})();

var my = new MyClass();

my.print();
my["publ"] = "öffentlich neu";

var priv = Symbol('priv');
my[priv] = "neues prop";

my.print();
console.log(my[priv]);

Bei Funktionen kann der Entwickler nun in der Funktionssignatur Parameter mit Standardwerten belegen. Bisher musste man nicht übergebene Parameter in der Methode selbst auf undefined prüfen und dann dort mit einem Wert belegen. Der Umgang soll so einfacher, expliziter und folglich weniger fehleranfällig In sein:

var hello = function(name, salutation="Guten Tag") {
console.log(salutation + " " + name);
};

hello("Martin", "Hi");
hello("Holger");

Eine Besonderheit im Vergleich zu anderen Sprachen ist die Möglichkeit zur Verwendung von Funktionsaufrufen. Durch sie lässt sich als Standard eine Funktion angeben, die aufgerufen wird, wenn kein Wert für den entsprechenden Parameter angegeben wurde. Damit kann man beispielsweise elegant prüfen, ob erforderliche Parameter definiert sind:

var check_required_arg = function(name) {
throw new Error("Parameter '" + name + "' ist erforderlich.");
};

var fkt = function(arg=check_required_arg("arg")) {
console.log(arg);
};

fkt("erforderlicher Wert");

try {
fkt();
} catch(err) {
console.log("FEHLER: " + err);
}

Der Umgang mit einer unbestimmt langen Liste von Parametern ist in Funktionen bisher nur über das Array this.arguments möglich. Das neue Sprachkonstrukt der "Rest-Parameter" vereinfacht ihre Behandlung: Dem letzten Parameter lassen sich drei Punkte (...) voranstellen, wodurch die JavaScript-VM alle weiteren übergebenen Werte als Array in ihm ablegt:

var fkt = function(salutation, ...names) {
names.forEach(function (name) {
console.log(salutation + " " + name);
});
};

fkt("Guten Tag", "Martin");
fkt("Hi", "Martin", "Holger");

Eine verwandte Neuerung ist die Konvertierung eines Arrays in eine konkrete Parameter-Liste. Ist es bisher notwendig, die Werte mit apply und dem Kontext an die Funktion zu übergeben, können Entwickler in ECMAScript 6 den neuen "Spread"-Operator (ebenfalls drei Punkte "...") verwenden.

// alt
let list = [10, 20, 30, 40];
console.log(Math.max.apply(Math, list));

// neu
console.log(Math.max(...list));

Das Fehlen echter Klassen und Vererbung war bisher die größte Schwäche von JavaScript. Klassen konnte man zwar über Funktionen simulieren, indem man eine Funktion mittels new aufruft, und auch für Vererbung gab es Mechanismen, die Frameworks wie underscore.js kapselten. Aber alle diese Strategien sind mit syntaktischen Nachteilen verbunden, und bei der Mischung von Frameworks gibt es Kompatibilitätsprobleme, sollten unterschiedliche Mechanismen zum Einsatz kommen.

In ECMAScript 6 kann der Entwickler nun Klassen, Properties und Vererbung direkt deklarieren, da entsprechende Konzepte zum Kern der Programmiersprache gehören. Zur Deklaration einer Klasse gibt es das Schlüsselwort class. Der Konstruktor wird mit constructor eingeleitet, wobei es wie in TypeScript nur einen Konstruktor geben darf. Er wird (anders als in Sprachen wie Java und C#) den abgeleiteten Klassen vererbt.