Funktionale Programmierung mit Objekten

the next big thing  –  22 Kommentare

JavaScript kennt verschiedene Methoden zur funktionalen Programmierung, beispielsweise map, reduce und filter. Allerdings stehen sie nur für Arrays zur Verfügung, nicht für Objekte. Mit ECMAScript 2019 lässt sich das jedoch auf elegante Weise ändern.

Schon vor knapp sechs Jahren habe ich im Rahmen der Serie Konsole & Kontext über die Funktionen map, reduce & Co. in JavaScript geschrieben. Sie sind nicht nur die klassischen Vertreter der sogenannten Funktionen höherer Ordnung, sondern stellen für viele Entwickler auch den Einstieg in die funktionale Programmierung dar. In JavaScript stehen sie dementsprechend auch schon seit Jahren serienmäßig für Arrays zur Verfügung.

Leider gilt das nicht für Objekte: Wer Schlüssel und/oder Werte eines Objekts mit einer Funktion wie map oder filter verarbeiten will, hat schlechte Karten. JavaScript kann das von Haus aus schlichtweg nicht. Abhilfe schafft die Bibliothek lodash, die eigene Varianten dieser Funktionen enthält, die auch mit Objekten umgehen können. Das ist zwar praktisch, allerdings ist man stets auf eine gesonderte Abhängigkeit angewiesen. Die Alternative, die gewünschten Funktionen selbst zu entwickeln, erspart einem diese Abhängigkeit zwar, wirkt ansonsten aber alles andere als attraktiv.

Neues in ECMAScript 2019

Mit ECMAScript 2019 steht nun ein weiterer Weg zur Verfügung, der ohne zusätzliche Abhängigkeit auskommt und der zugleich ohne umständliche Konstrukte von Hand auskommt. Eine Neuerung der neuen Sprachversion ist nämlich die Funktion fromEntries, die ein Objekt aus einem Array von Arrays zusammensetzen kann. Technisch gesprochen bildet sie das Gegenstück zur Object.entries-Funktion.

Die bereits bekannte Funktion zerlegt ein Objekt in ein Array, wobei aus jedem Schlüssel-Wert-Paar ein eigenes Array mit zwei Elementen wird. Auf dem Weg lässt sich das Objekt

const versions = {
node: '10.16.0',
npm: '6.10.2',
express: '4.17.1'
};

const versionsAsArray = Object.entries(versions);

in das verschachtelte Array

console.log(versionsAsArray);
// => [
// [ 'node', '10.16.0' ],
// [ 'npm', '6.10.2' ],
// [ 'express', '4.17.1' ]
// ]

verwandeln. Die Funktion Object.fromEntries bewirkt nun genau das Gegenteil und transformiert das Array wieder in das ursprüngliche Objekt zurück.

Diese Dualität der beiden Funktionen kann man sich nun zunutze machen, um ein Objekt zunächst mit Hilfe von Object.entries in ein Arrays zu verwandeln, dieses dann mit Hilfe der klassischen Funktionen zur funktionalen Programmierung zu verarbeiten, um es abschließend mit Object.fromEntries wieder in ein Objekt zurück zu wandeln.

Ein Filter für Objekte

Will man beispielsweise aus dem vorigen Beispiel nur jene Versionsnummern erhalten, deren Schlüssel mit dem Buchstaben n beginnt, lässt sich das leicht wie folgt umsetzen:

const filteredVersions = Object.fromEntries(
Object.entries(versions).
filter(([ key, value ]) => key.startsWith('n'))
);

console.log(filteredVersions);
// => {
// node: '10.16.0',
// npm: '6.10.2'
// }

Das gleiche Vorgehen funktioniert selbstverständlich auch für alle anderen Funktionen, mit denen sich Arrays verarbeiten lassen. Kapselt man den Aufruf gegebenenfalls noch in einer eigenen Funktion, hat man mit wenigen Zeilen und kaum eigenem Aufwand eine komfortable Alternative geschaffen, um funktionale Programmierung auch auf Objekten in JavaScript anwenden zu können.

tl;dr: ECMAScript 2019 enthält die neue Funktion Object.fromEntries, die es auf einfache Weise ermöglicht, die Funktionen von Arrays auch auf Objekte anzuwenden. Das lässt sich beispielsweise für die funktionale Programmierung elegant nutzen.