Neue Sprachfeatures im ECMAScript-6-Entwurf – Teil 1

Seite 3: Vererbung, Module und Iteratoren

Inhaltsverzeichnis

Das Ableiten von einer anderen Klasse zeigt der Entwickler mit extends an (vgl. z.B. Java, Dart, TypeScript). Get- und Set-Funktionen für Properties leiten die Schlüsselwörter get beziehungsweise set ein. Allerdings fasst man sie nicht wie in C# zu einem Block zusammen, sondern erfasst sie wie in Java, ActionScript, Dart und TypeScript getrennt. Dennoch sind in abgeleiteten Klassen sowohl Getter als auch Setter neu zu implementieren, selbst wenn nur einer von beiden sich gegenüber der Basisklasse ändert (siehe Klasse PKW im folgenden Quellcodeauszug). Auch von den eingebauten Standardobjekten wie Date, Array und Element lässt sich erben.

class Auto {
constructor(max_geschwindigkeit) {
this._max_geschwindigkeit = max_geschwindigkeit;
this._aktuelle_geschwindigkeit = 0;
}

get aktuelle_geschwindigkeit() {
return this._aktuelle_geschwindigkeit;
}

set aktuelle_geschwindigkeit(value) {
if (value >= this._max_geschwindigkeit) {
throw new Error("Geschwindigkeit über '" + this._max_geschwindigkeit + "' ist nicht möglich.");
}

this._aktuelle_geschwindigkeit = value;
}

drive() {
console.log("Fahre " + this._aktuelle_geschwindigkeit + ".");
}
}

class LKW extends Auto {
constructor() {
super(80);
}
}

class PKW extends Auto {
constructor(max_geschwindigkeit) {
super(max_geschwindigkeit);
}

get aktuelle_geschwindigkeit() {
return this._aktuelle_geschwindigkeit;
}

set aktuelle_geschwindigkeit(value) {
if (value >= this._max_geschwindigkeit) {
throw new Error("Geschwindigkeit über '" +
this._max_geschwindigkeit + "' ist nicht möglich.");
}

if (value > 130) {
console.log("Verbrauch ist sehr hoch!");
}

this._aktuelle_geschwindigkeit = value;
}

drive() {
super();
if (this._aktuelle_geschwindigkeit > 130) {
console.log("Bei einem Umfall muss mit der Zurechnung
einer Teilschuld gerechnet werden.")
}
}
}

let lkw = new LKW();
let pkw = new PKW(250);

lkw.aktuelle_geschwindigkeit = 75;
console.log(lkw.aktuelle_geschwindigkeit);
lkw.drive();


pkw.aktuelle_geschwindigkeit = 180;
console.log(pkw.aktuelle_geschwindigkeit);
pkw.drive();

Unter Node.js hat sich ein Modulsystem basierend auf Common.js etabliert, im Browser wird hingegen meist die Asynchronous Module Definition (AMD) für Abhängigkeiten und zum Laden von JavaScript-Dateien verwendet. Auch hier liefert ECMAScript 6 nun den längst überfälligen Standard, der sowohl das explizite Exportieren und das spezifische Importieren von Modulen, Klassen, Funktionen et cetera ermöglicht.

// Exportieren von Variablen 
export var firstname = "Martin";
export var lastname = "Möllenbeck";
export var position = "Geschäftsführer";

// Exportieren von Funktionen
export var fkt = function(name) {
console.log("Hallo " + name);
};

// Exportieren einer Klasse
export class MyClass {

}

// Standard-Export
export default function default_fkt() {
console.log("Standard-Funktion");
};

Das obige Beispiel zeigt, wie sich Variablen, Funktionen und Klassen exportieren lassen. Als Besonderheit kann man zudem mit dem Schlüsselwort default einen Standardexport definieren.

// Die Variablen 'firstname' und 'lastname' importieren
import {firstname, lastname} from './02_export';

console.log(firstname);
console.log(lastname);

// Die Funktion 'fkt' als 'hello_world' importieren und die Klasse
// mit dem exportierten Namen 'MyClass' importieren
import {fkt as hello_world, MyClass} from './02_export';

hello_world("Welt");

let myClass = new MyClass();

// Default importieren
import default_fkt from './02_export';

default_fkt();

An diesem Codeausschnitt lässt sich gut erkennen, wie Variablen importiert werden und der Name des exportierten Symbols angepasst wird (import {export_symbole as neuer_name} from...). Exportiert das Modul ein Standardsymbol (Variable, Klasse oder Funktion), können die geschweiften Klammern beim Import entfallen.

Für die Iteration über Objektmengen bietet ECMAScript 6 das neue Schleifenkonstrukt for/of, das vergleichbar mit foreach in C# ist:

for (let item of [1, 2, 3]) {
console.log(item);
}

Nicht nur Arrays mit einem entsprechenden Iterator sind in solchen Schleifen verwendbare Objektmengen – unter ECMAScript 6 ist es möglich, beliebige eigene Objekte als Iterator zu verwenden:

function interateRandoms(min, max, count) {
return {
[Symbol.iterator]: function() {
var index = 0;
var current = 0;

return {
next: function() {
if (index < count) {
index++;
current = Math.round(Math.random()*
(max-min))+min;
return {
value: current,
done: false
};
} else {
return {
value: undefined,
done: true
}
}
}
};
}
};
}

var iter = interateRandoms(5, 10, 3);

for (var item of iter) {
console.log(item);
}

Dazu wird der Funktion (interateRandoms) min, max und die Anzahl (count) der gewünschten Zufallszahlen übergeben. Als Erstes liefert sie ein Objekt zurück, das eine Iteratorfunktion enthält. Sie ist mit dem Konstrukt [Symbole.iterate] gekennzeichnet und liefert wieder ein Objekt mit einer next-Funktion. Letztere liefert jeweils den nächsten Zufallszahlenwert in Form eines Tupels aus value und done. Die Iteration ist vom Aufrufer zu beenden, wenn done den Wert true liefert.