Evolution im Web: ECMAScript 2017

Seite 3: Werte und Einträge von Objekten

Inhaltsverzeichnis

Die Funktion Object.keys() existiert seit geraumer Zeit in ECMAScript. Sie nimmt ein Objekt als Parameter entgegen und gibt dessen aufzählbare Eigenschaften zurück – vom Prototypen geerbte Eigenschaften sind nicht eingeschlossen.

Object.keys({foo: 1, bar: 'baz', qux: 3});
// > ["foo", "bar", "qux"]

ECMAScript 2017 führt die Methoden Object.values() und Object.entries() ein, deren Funktion sich aus dem Namen erschließen lässt: Erstere ist das Gegenstück zu Object.keys() und gibt die Werte der eigenen (nicht geerbten) aufzählbaren Eigenschaften zurück:

Object.values({foo: 1, bar: 'baz', qux: 3});
// > [1, "baz", 3]

Object.entries() gibt die Name-Wert-Paare der Objekteigenschaften zurück:

Object.entries({foo: 1, bar: 'baz', qux: 3});
// > [["foo", 1], ["bar", "baz"], ["qux", 3]]

Alle drei Methoden nehmen auch Arrays entgegen, die in JavaScript ebenfalls schlicht Objekte darstellen. Bei Arrays oder Objekten mit numerischen Schlüsseln erfolgt die Rückgabe immer nach deren aufsteigender Sortierung:

Object.entries({'3': 1, '4': 'baz', '1': 3});
// > [["1", 3], ["3", 1], ["4", "baz"]]

Die Funktionen dürften für viele Entwickler äußerst nützlich sein, beispielsweise zum Aufbau von Tabellen oder Listen, die alle Eigenschaften eines Objektes aufzählen. Besonders interessant ist das für Objekte, die dynamisch zusammengesetzt oder von einem Webservice übertragen werden und deren genauer Aufbau der Anwendung somit nicht bekannt ist.

Alle aktuellen Ausgaben der relevanten Browser und die Serverplattform Node.js sowie die Transpiler Babel und TypeScript unterstützen die Funktionen.

Eine weitere neue Funktion behandelt ebenfalls die eigenen, nicht geerbten Eigenschaften eines Objekts, und zwar die sogenannten Eigenschaften-Deskriptoren. ECMAScript definiert unterschiedliche Arten von Eigenschaften: einerseits Data Properties, die Daten enthalten, andererseits Accessor Properties, die über Zugriffsfunktionen (Getter und Setter) angesprochen werden.

Um eine bestimmte Eigenschaft eines Objektes genauer zu untersuchen, können sich Entwickler beschreibende Informationen ausgeben lassen. Dazu dient die Methode getOwnPropertyDescriptor, die seit ECMAScript 5 zum Sprachumfang gehört. Die Option, Eigenschaften mit ausschließlichem Lesezugriff oder Gettern und Settern auszustatten, ist ebenfalls seit ECMAScript 5 Bestandteil des Sprachstandards.

Die Methode getOwnPropertyDescriptor nimmt ein Objekt und den Namen einer Eigenschaft entgegen und gibt den zugehörigen Eigenschaftendeskriptor zurück:

const foo = {bar: 'baz'};
Object.getOwnPropertyDescriptor(foo, 'bar');
> Object {value: "baz",
> writable: true,
> enumerable: true,
> configurable: true}

Die Eigenschaft bar des Objektes foo enthält also einen bestimmten Wert und ist schreibbar (durch Zuweisung), aufzählbar (in for-in-Schleifen) sowie konfigurierbar (Löschen der Eigenschaft, Transformation in eine Accessor Property oder Ändern seiner Attribute ist möglich). Bei der Accessor Property sieht die Rückgabe wie folgt aus:

const foo = { get bar() { return 'baz'; } };
Object.getOwnPropertyDescriptor(foo, 'bar');
> Object {enumerable: true,
> configurable: true,
> set: undefined,
> get: function bar()}

Hier lassen sich die Setter- und Getter-Funktionen beziehen, sofern sie definiert sind, die Eigenschaften der Aufzählbarkeit und Konfigurierbarkeit sind ebenfalls vorhanden. Die neue Funktion getOwnPropertyDescriptors (im Gegensatz zur alten im Plural) nimmt als einzigen Parameter lediglich ein Objekt entgegen und gibt alle eigenen Eigenschaftendeskriptoren des Objektes in Form einer Objektstruktur zurück:

const foo = { get bar() { return 'baz'; }, qux: 'quux' }
Object.getOwnPropertyDescriptors(foo);
> Object {
> bar: {
> configurable: true,
> enumerable: true,
> get: function bar(),
> set: undefined
> },
> qux: {
> configurable: true,
> enumerable: true,
> value: "quux",
> writable: true
> }
> }

Anwendungsprogrammierer werden vermutlich weniger Berührungspunkte mit Object.getOwnPropertyDescriptors() haben als Entwickler von Bibliotheken und Frameworks – insbesondere im Hinblick auf den Umgang mit Dekoratoren. Die aktuellen Browser unterstützen die Funktion ebenso wie Node.js, Babel und TypeScript.

Im März 2016 kam es zu einem fatalen Debakel durch das kleine npm-Paket "left-pad", das eine einfache Methode bietet, einen String auf eine bestimmte Zeichenlänge aufzufüllen, indem es von der linken Seite Zeichen einschiebt. Nachdem der Paketverwalter infolge eines Streits mit dem Marktplatzbetreiber das Paket entfernte, scheiterten etliche Softwareprojekte wie Node.js oder Babel beim Build.

Die Notwendigkeit für ein solches Paket entfällt künftig, da String-Padding nativ in den Sprachumfang von JavaScript einzieht und zwar durch die beiden Funktionen String.prototype.padStart() und String.prototype.padEnd(). Für beide Methoden lässt sich die gewünschte Zielzeichenlänge (für den gesamten String, nicht die Zahl der eingefügten Zeichen) angegeben. padStart schiebt analog zum "left-pad"-Paket Zeichen von der linken Seite ein, padEnd dagegen von der rechten. Die Ziellänge bestimmt jeweils der erste Parameter, der optionale zweite nimmt eine Zeichenkette entgegen, die zum Auffüllen der ursprünglichen Zeichenkette zum Einsatz kommt. Fehlt der zweite Parameter, zieht das System das Leerzeichen (U+0020) zum Auffüllen heran.

'heise'.padStart(10);            // "     heise"
'heise'.padStart(1); // "heise"
'heise'.padStart(10, '~'); // "~~~~~heise"
'heise'.padEnd(10); // "heise "
'heise'.padEnd(10, 'dev'); // "heisedevde"
'heise'.padEnd(10, 'developer'); // "heisedevel"

Die beiden Funktionen sind für viele Entwickler sehr hilfreich, beispielsweise bei der Ausgabe hexadezimaler Werte wie 000F, 001A oder A10F in festen Längen. Die aktuellen Browser unterstützen die Funktionen ebenso wie die aktuelle Fassung der Serverplattform Node.js sowie Babel und TypeScript.

JavaScript erlaubt bei der Definition von Objekten oder Arrays ein abschließendes Komma, das jedoch ignoriert wird. Was sich zunächst überflüssig anhört, kann sich als recht nützlich erweisen: Versionskontrollsysteme wie Git arbeiten auf Zeilenbasis. Muss zum Hinzufügen einer Zeile erst noch in der vorhergehenden ein Komma eingefügt werden, ergeben sich effektiv Änderungen in zwei Zeilen. Problematisch ist zudem, dass der ursprüngliche Autor (git blame) der ersten Zeile nun überschrieben wird.

{
foo: 1,
bar: 2,
baz: 3, // die nächste Eigenschaft erfordert
// kein Ändern der Zeile
}

Bei Parameter-Auflistungen von Funktionen lässt sich dieses Prinzip bislang nicht verwenden:

function myFunction(
foo,
bar,
baz, // vor ES 2017 SyntaxError, jetzt OK
)

Und ebensowenig bei Argumentaufzählungen beim Aufruf der zugehörigen Funktion:

myFunction(
'foo',
'bar',
'baz',// vor ES 2017 SyntaxError, jetzt OK
)

Dass ECMAScript 2017 somit auch abschließende Kommas bei Parameter- und Argumentauflistungen erlaubt, kommt allen Zielgruppen entgegen. Besondere Nutznießer sind Entwickler, die bestimmte Codeformatierungen anwenden wollen, etwa in Kombination mit der Versionsverwaltung. Die aktuellen Browser unterstützen die Funktionen ebenso wie die aktuelle Fassung der Serverplattform Node.js sowie Babel und TypeScript.