JavaScript/Destrukturierung

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Unter Destrukturierung versteht man in JavaScript eine besondere Syntax, mit der Werte von Objekteigenschaften oder Elemente eines iterierbaren Objektes an Variablen, Konstanten, Parameter von Funktionen oder Eigenschaften eines anderen Objektes gebunden werden können.

ToDo (weitere ToDos)

Zu weitschweifig, Erklärung lemmafremder Basics muss raus, Themenreihenfolge ist suboptimal. Prüfen ob zu Arrays nicht mehr zu sagen ist


Allgemeine Beschreibung

Destrukturierungsausdrücke vereinfachen bestimmte, häufig wiederkehrende Abläufe bei der Arbeit mit zusammengesetzten Datentypen wie Objekten oder Arrays. Soll zum Beispiel der Wert einer Objekteigenschaft an eine Variable gebunden werden, um die wiederholte Referenzierung des Objektes zu vermeiden, dann würde ohne Destrukturierung der Eigenschaftsname zweimal notiert werden – einmal als Bezeichner der Variable und einmal beim Zugriff auf die Eigenschaft.


Beispiel
// Define ordinary object

let object = {
    property: 'value'
};


// Assign to variable using member expression

let property = object.property;


Handelt es sich wie in dem Beispiel oben nur um eine einzelne Eigenschaft, deren Wert an eine Variable gebunden werden soll, dann ist der Bedarf an einer kürzeren Schreibweise nicht direkt ersichtlich. Sollen jedoch mehrere Eigenschaften eines Objektes gelesen und ihr Wert in Variablen hinterlegt werden, dann entsteht bald der Wunsch nach einer kompakteren Schreibweise.


Beispiel
// Define ordinary object

let object = {
    property: 'value'
};


// Assign to variable using object assignment pattern

let {property} = object;


Die Syntax für die Destrukturierung von Objekten löst dieses Problem. Wie in dem Beispiel oben zu sehen ist, wird hierbei auf der rechten Seite des Zuweisungsausdrucks nur eine Referenz auf das Objekt notiert. Auf der linken Seite werden – von geschweiften Klammern eingeschlossen – die Namen der Objekteigenschaften notiert, deren Wert an Variablen gebunden werden soll. Die wiederholte Referenzierung des Objektes und die doppelte Angabe des Eigenschaftsnamens entfällt.


Beispiel
// Object assignment pattern

const {name, age} = {name: 'Jane', age: 25};


// Array assignment pattern

const [head] = [1, 2, 3];


Es wird grundsätzlich zwischen zwei Destrukturierungsmustern unterschieden. Bei der Destrukturierung von gewöhnlichen Objekten wird direkt auf bestimmte Eigenschaften des destrukturierten Objektes zugegriffen und ihr Wert an einen Bezeichner gebunden. Bei der Destrukturierung von iterierbaren Objekten, wie zum Beispiel von Arrays, wird hingegen über das Objekt iteriert und die Elemente werden in der Reihenfolge an die angegebenen Bezeichner gebunden, in der sie ausgegeben wurden.


Beispiel
// Apply object assignment pattern to an iterable object

const {length} = [1, 2, 3];


Das verwendete Muster für die Destrukturierung wird allerdings nicht durch den Typ des destrukturierten Objektes vorgegeben. So ist zum Beispiel ein Array ein iterierbares Objekt, aber wie in dem Beispiel oben zu sehen ist, kann trotzdem mittels Objektdestrukturierung auf Eigenschaften des Arrays zugegriffen werden.


Objektdestrukturierung

Objekte zur Kapselung von Daten sind in JavaScript allgegenwärtig. Das liegt zum einen daran, dass es lange Zeit keine echten Alternativen zur Verwendung von Objekten gab. Zum anderen liegt es daran, dass die Sprache eine sehr elegante Syntax für die Definition von Objekten bereitstellt. Die Literalschreibweise für ein Objekt besteht aus nicht mehr als einem Paar geschweifter Klammern, das eine Liste von Eigenschaftsdefinitionen umschließt.


Beispiel
// Object initializer syntax

const Earth = {
    type: 'Planet',
    satellites: true,
    color: 'blue'
};


// Reference properties with member expressions

let type = Earth.type, color = Earth.color;


Möchte man hingegen auf mehrere Eigenschaften eines bereits definierten Objekts zugreifen, so ist dies mit ungleich mehr Aufwand verbunden. Es muss für jede Eigenschaft das Objekt referenziert und der Eigenschaftsname angegeben werden, zusätzlich zu dem Bezeichner, an den der Wert der Eigenschaft gebunden werden soll, auch dann, wenn wie in dem Beispiel oben Bezeichner und Eigenschaftsnamen identisch sind. Das ist unnötig umständlich und begünstigt Fehler, weshalb diese Art des Zugriffs keine befriedigende Lösung darstellt.



Die Objektdestrukturierung stellt eine elegante Alternative für den Zugriff auf Objekteigenschaften dar, die syntaktisch der Objektdefinition in Literalschreibweise ähnelt. Es werden an geeigneter Stelle einfach geschweifte Klammern notiert und darin eine Liste von Eigenschaftsnamen. Je nach Kontext werden die Werte der auf diese Weise referenzierten Eigenschaften dann in Variablen, Konstanten oder Parametern von Funktionen hinterlegt.


Beispiel
// Object initializer syntax

const Mars = {
    type: 'Planet',
    satellites: true,
    color: 'red'
};


// Assign to variables using object assignment pattern

let {type, color} = Mars;


Anders als in dem ersten Beispiel oben, wird hier das zuvor in Literalschreibweise definierte Objekt bei der Variablendeklaration destrukturiert. Sowohl in diesem als auch im letzten Beispiel werden die Werte der beiden referenzierten Objekteigenschaften in gleichnamigen Variablen gespeichert, aber die Variante bei der das Objekt destrukturiert wird ist deutlich kürzer, wodurch die Lesbarkeit verbessert wird.


Zuweisungsausdrücke für Variablen und Konstanten

Bei der Objektdestrukturierung zum Zwecke der Zuweisung von Eigenschaftswerten an Variablen oder Konstanten sind im Wesentlichen zwei Fälle zu unterscheiden. Der erste Fall betrifft die Zuweisung bei der Deklaration der Variablen oder Konstanten. Hier wird zunächst wie üblich das Schlüsselwort let oder const notiert und danach der Destrukturierungsausdruck, gefolgt von einem Gleichzeichen und einem Ausdruck, dessen Wert eine Referenz auf das Objekt ist, das destrukturiert werden soll.


Beispiel
// Object definition

const border = {
    color: 'green',
    style: 'dashed',
    width: 'thin'
};


// Declaration of a constant using object destructuring

const {color, width} = border;


// Variable declaration using object destructuring

let {style} = border;


Der zweite Fall betrifft die Zuweisung von Eigenschaftswerten an Variablen, die bereits deklariert wurden. Hier ist die Syntax im Prinzip dieselbe wie bei der Deklaration, jedoch ohne das Schlüsselwort let. Anders als bei Variablen die mit var deklariert werden, führt hier eine erneute Deklaration im selben Scope zu einem Syntaxfehler der dazu führt, dass das Programm nicht ausgeführt wird.


Beispiel
// Object definition

const animation = {
    name: 'epileptic-seizure',
    duration: 0.1,
    iterationCount: 1000,
    direction: 'alternate',
    playState: 'paused'
};


// Declare variables without assignment

let name, playState;


// Assign to variables using object assignment pattern

({name, playState} = animation);


Ein weiterer Unterschied ist, dass in diesem Fall der gesamte Zuweisungsausdruck in runde Klammern gefasst werden muss. Der Grund dafür ist, dass die geschweiften Klammern sonst als Anweisungsblock interpretiert würden. Ein solcher kann auch abseits von Funktionen und Kontrollstrukturen für sich alleine stehen. Das nachfolgende Gleichheitszeichen würde dementsprechend einen Syntaxfehler produzieren.


Hinweis:

Anders als in vielen vergleichbaren Programmiersprachen, ist die Notation eines Semikolons am Ende einer Anweisung in JavaScript nicht zwingend vorgeschrieben. Ein solches wird bei Bedarf automatisch eingefügt. Werden Anweisungen nicht explizit mit einem Semikolon beendet, dann ist es möglich, dass die runden Klammern um den Zuweisungsausdruck als Funktionsaufruf interpretiert werden. Dies gilt es also zu beachten.


Zuweisungsausdrücke für Funktionsparameter

Destrukturierungsausdrücke können nicht nur im Zusammenhang mit der Zuweisung von Eigenschaftswerten an Variablen oder Konstanten verwendet werden. Es können auch Objekte destrukturiert werden, die einer Funktion als Argument übergeben werden. Dabei wird der Destrukturierungsausdruck an der Stelle des Parameters der Funktion notiert, an der ein Objekt erwartet wird.


Beispiel
// Ordinary function definition

function handler({type, target}) {

    // Print information about the event

    console.log(`Event ${type} has been dispatched to ${target.tagName}.`);
}


In dem Beispiel oben wird ein Eventhandler definiert, der als Argument ein Objekt mit Informationen über das eingetretene Ereignis erwartet. Da hier lediglich der Inhalt der Eigenschaften type und target des Eventobjektes von interesse ist, wird statt eines normalen Parameternamens ein Destrukturierungsausdruck angegeben. Dabei wird innerhalb der runden Klammern für die Parameterliste ein Paar geschweifte Klammern notiert und darin die Namen der beiden Eigenschaften, deren Wert innerhalb der Funktion verwendet werden soll.


Beispiel
// Arrow function definition

const scale = ({value}, factor) => ({value: factor * value});


Ein Ausdruck zur Objektdestrukturierung kann – wie in dem Beispiel oben zu sehen ist – auch zusammen mit gewöhnlichen Parametern notiert werden. Der Ausdruck nimmt einfach eine Stelle in der Parameterliste ein. Wird wie oben eine Pfeilfunktion definiert, dann ist allerdings zu beachten, dass bei der Destrukturierung eines Objekts zwingend runde Klammern um die Liste der Parameter notiert werden müssen, selbst dann, wenn nur ein Argument erwartet wird, wobei die Klammern normalerweise weggelassen werden könnten.


Hinweis:

Wird wie in dem letzten Beispiel von einer Pfeilfunktion ein Objekt zurückgegeben, dann müssen auch um das Objektliteral herum runde Klammern notiert werden, da die geschweiften Klammern sonst als Anweisungsblock interpretiert werden, der den Körper der Funktion umschließt. Der Doppelpunkt würde in diesem Fall zu einem Syntaxfehler führen.


Benötigt eine Funktion mehr als zwei oder drei Parameter, dann ist es regelmäßig eine gute Idee, statt einzelner Werte ein Objekt zu übergeben, in dem die Werte hinterlegt sind. Dadurch spielt es keine Rolle mehr, in welcher Reihenfolge die Argumente beim Funktionsaufruf notiert werden müssen, was den Code weniger fehleranfällig macht. Darüber hinaus wird durch die Benennung der übergebenen Werte die Lesbarkeit des Codes verbessert. Mittels Destrukturierung kann dann auf die Werte genauso einfach zugegriffen werden wie auf gewöhnliche Parameter.


Angabe eines Standardwertes

Soll die Übergabe eines Objekts an eine Funktion optional sein, dann muss für den entsprechenden Parameter der Funktion ein Objekt als Standardwert angegeben werden, wenn das als Argument übergebene Objekt direkt in der Parameterliste destrukturiert werden soll. Wird kein Standardwert angegeben, dann führt der Aufruf ohne Argumente zu einem Typfehler, da Parameter für die kein Argument übergeben wurde mit dem primitiven Wert undefined initialisiert werden, der nicht implizit in ein Objekt konvertiert wird.


Beispiel
// Define function with default parameter

function maybeAssign(object, {value} = {}) {

    // Parameter is undefined if no object is provided

    if (value) {
        object.property = value;
    }

    return object;
}


Auch wenn ein in der Parameterliste einer Funktion ein Destrukturierungsausdruck notiert wird, ändert sich an der Syntax für die Definition eines Defaultparameters nichts. Der Ausdruck tritt wie oben zu sehen ist einfach an die Stelle des Parameternamens. Dahinter wird wie üblich ein Gleichheitszeichen und der Ausdruck notiert, dessen Wert beim Fehlen eines Arguments eingesetzt werden soll, in dem Beispiel oben einfach ein leeres Objekt.



Der hinter dem Gleichheitszeichen notierte Ausdruck wird nur ausgewertet, wenn das Argument für die Position des Parameters den Wert undefined hat. Das bedeutet, dass Eigenschaften eines als Standardwert notierten Objektes nicht als Ersatz für fehlende Eigenschaften eines übergebenen Objektes dienen können. Soll für eine Eigenschaft ein Standardwert angegeben werden, dann muss dies innerhalb des Destrukturierungsausdrucks erfolgen.


Verwendung von berechneten Eigenschaftsnamen

Bei der Definition einer Objekteigenschaft muss der Name der Eigenschaft nicht zwingend als Literal notiert werden, unabhängig davon, auf welche Weise die Definition erfolgt. Wird eine Eigenschaft in einem Objektliteral definiert, dann kann an Stelle des Namens der Eigenschaft ein Paar eckige Klammern notiert werden und darin ein beliebiger Ausdruck, der zum Eigenschaftsnamen aufgelöst wird. Analog dazu kann auch bei der Destrukturierung ein berechneter Eigenschaftsname verwendet werden.


Beispiel
// Object destructuring with computed property name

function when(condition, {[condition ? 'whenTrue' : 'whenFalse']: value}) {
    return value;
}


// Call function and store value

const value = when(true, {whenTrue: 1, whenFalse: 0});


In dem Beispiel oben wird eine Funktion definiert, die als zweiten Parameter ein Objekt erwartet, das direkt in der Parameterliste destrukturiert wird. Dabei wird der Name der Objekteigenschaft auf die zugegriffen werden soll – abhängig vom Wert des ersten Parameters – dynamisch berechnet und der Eigenschaftswert an den Bezeichner value gebunden, der nach dem Ausdruck zur Berechnung des Namens und einem Doppelpunkt notiert wird.


Beispiel
// Object destructuring with computed property name

function unless({condition, [condition ? 'whenFalse' : 'whenTrue']: value}) {
    return value;
}


// Call function and store value

const value = unless({condition: false, whenTrue: 1, whenFalse: 0});


Anders als im ersten Beispiel könnte der Parameter condition für die Bedingung im ternären Ausdruck zur Berechnung der zu referenzierenden Objekteigenschaft auch selbst als Eigenschaft notiert werden, so wie in diesem Beispiel. Zu beachten ist aber, dass nur auf solche Bezeichner zugegriffen werden kann, für die zum Zeitpunkt des Zugriffs bereits eine Bindung im lokalen Scope existiert. Dabei spiel es keine Rolle, ob es sich um einen formalen Parameter oder um eine Eigenschaft eines oder desselben als Argument übergebenen Objektes handelt.


Bestimmung eines anderen Bezeichners an Stelle des Eigenschaftsnamens

Es ist möglich, bei der Destrukturierung eines Objektes für eine Eigenschaft einen anderen Bezeichner zu bestimmen als den Namen dieser Eigenschaft. Das kann erforderlich sein, weil der Eigenschaftsname kein gültiger Bezeichner ist, oder weil es im jeweiligen Scope bereits eine Bindung für den Namen der Eigenschaft gibt.


Beispiel
// Use a different identifier for the property

let {propertyName: variableName} = {propertyName: 'value'};


Die Syntax für die Umbenennung entspricht weitestgehend der Syntax bei der Verwendung von berechneten Eigenschaftsnamen. Das heißt, es wird zunächst der Name der Objekteigenschaft notiert, dann ein Doppelpunkt und schließlich der Bezeichner, an den der Wert der Eigenschaft gebunden werden soll. Für den Namen der Eigenschaft wird bei dieser Notation grundsätzlich keine Bindung angelegt.


Eigenschaftsname enthält unerlaubte Zeichen

Ein Grund dafür, dass bei der Destrukturierung eines Objekts ein anderer Bezeichner für eine Eigenschaft gewählt werden muss ist, dass der Eigenschaftsname für Bezeichner unerlaubte Zeichen enthält, oder aber grundsätzlich erlaubte Zeichen an der falschen Stelle, etwa Ziffern am Anfang des Wortes.


Beispiel
// Assign to valid identifier

let {'--custom-property': customProperty} = {'--custom-property': 'value'};


Wird ein Eigenschaftsname in Anführungszeichen notiert, kann eine beliebige Zeichenkette als Name verwendet werden. Handelt es sich bei dem Namen wie in dem Beispiel oben nicht um einen validen Bezeichner, wird eine Umbenennung vorgenommen, indem zunächst der ungültige Eigenschaftsname in Anführungszeichen und danach der Bezeichner notiert wird, an den der Eigenschaftswert gebunden werden soll.


Eigenschaftsname ist reserviertes Wort

Sowohl bei der Definition von Objekten in Literalschreibweise als auch beim Zugriff auf Objekteigenschaften über Elementausdrücke können reservierte Wörter ohne Anführungszeichen als Eigenschaftsname verwendet werden. Als Bezeichner für Variablen, symbolische Konstanten oder Parameter von Funktionen sind sie aber entweder grunsätzlich oder zumindest in bestimmten Kontexten ungültig.


Beispiel
// Defuse property name that is reserverd word

let {for: _for} = {for: 'you'};


So wie in einem Objektliteral, kann ein reserviertes Wort auch innerhalb eines Destrukturierungsausdrucks ohne Anführungszeichen notiert werden. Häufig wird bei der Wahl eines alternativen Bezeichners für ein reserviertes Wort einfach ein Unterstrich vorangestellt, so wie in dem Beispiel oben.


Eigenschaftsname ist Symbol

Als Name für eine Objekteigenschaft können nicht nur Werte vom Datentyp String eingesetzt werden, sondern auch Symbole. Die Syntax für berechnete Eigenschaftsnamen macht es möglich, bei der Destrukturierung eines Objekts auch solche Eigenschaften zu referenzieren. Hier ist zu unterscheiden zwischen Symbolen die nur lokal sichtbar sind und Symbolen, die im globalen Symbolregister hinterlegt sind.


Beispiel
// Store local symbol in constant

const propertyName = Symbol();


// Define object using the symbol as property name

const object = {
    [propertyName]: 'value'
};


// Store value using object destructuring

let {[propertyName]: variableName} = object;


// Print value

console.log(variableName); // value


Handelt es sich so wie in dem Beispiel oben um eine Eigenschaft, deren Name ein lokal sichtbares Symbol ist, dann genügt es innerhalb von eckigen Klammern eine Referenz auf das Symbol zu notieren, sowohl bei der Definition der Eigenschaft als auch bei der späteren Referenzierung innerhalb des Destrukturierungsausdrucks. Wird das jeweilige Symbol so wie oben durch den Aufruf der Funktion Symbol erzeugt, dann muss eine Referenz auf das Symbol sichtbar sein, damit die zugehörige Eigenschaft referenziert werden kann. Auf diese Weise erzeugte Symbole werden nämlich nicht im globalen Symbolregister gespeichert.


Beispiel
// Create object with global symbol as property name

function global() {
    return {
        [Symbol.for('peace')]: 'dove'
    };
}


// Destructure object using global symbol

const {[Symbol.for('peace')]: symbol} = global();


// Print value

console.log(symbol); // dove


In diesem Beispiel ist aus Sicht der Anweisung, die den Destrukturierungsausdruck enthält, kein Bezeichner sichtbar an den ein Symbol gebunden wäre. Das Symbol, das bei der Erzeugung des Objekts durch die Funktion als Eigenschaftsname verwendet wurde, ist jedoch im globalen Symbolregister verzeichnet, da hier die Methode for des Symbolobjektes verwendet wurde. Durch den erneuten Aufruf dieser Methode kann eine Referenz auf das Symbol geholt und als Eigenschaftsname bei der Destrukturierung eingesetzt werden.



Destrukturierung von mehreren verschachtelten Objekten

Objekte sind hervorragend dazu geeignet, hierarchische Zusammenhänge zu modellieren. Strukturen wie Graphen oder Bäume können auf Objekte abgebildet werden, die als Eigenschaften wiederum Referenzen auf andere Objekte besitzen. Ein Objekt muss also nicht zwingend eine flache Liste von Eigenschaften darstellen, sondern kann gegebenenfalls andere Objekte enthalten. Solche verschachtelten Objekte können ebenfalls in ein und demselben Ausdruck destrukturiert werden. Dabei können auch verschiedene Destrukturierungsmuster gemischt werden.


Eigenschaft ist gewöhnliches Objekt

Soll innerhalb eines Destrukturierungsausdrucks auf die Eigenschaften eines Objekts zugegriffen werden, das der Wert einer Eigenschaft des destrukturierten Objekts ist, dann wird zu diesem Zweck zuerst der Name der entsprechenden Eigenschaft notiert, gefolgt von einem Doppelpunkt und schließlich dem Muster für die Destrukturierung des verschachtelten Objekts.


Beispiel
// Define nested object

const outer = {
    inner: {
        property: 'value'
    }
};


// Assign property of nested object

const {
    inner: {
        property
    }
} = outer;


// Print value

console.log(property);


Zum besseren Verständnis ist in dem abstrakten Beispiel oben der Destrukturierungsausdruck der Schachtelung der Objekte gemäß formatiert, statt ihn wie üblich in einer Zeile zu notieren. So ist viel besser zu erkennen, dass der Ausdruck genau die Struktur der Objekte widerspiegelt. Es wird bloß keine Eigenschaft definiert, sondern nur über den Namen auf die Eigenschaft zugegriffen und ihr Wert in einer gleichnamigen Konstante hinterlegt.


Beispiel
// Define custom event

const earthquake = new CustomEvent('earthquake', {
    bubbles: true,
    detail: {
        scale: 9.5,
        type: 'megathrust'
    }
});


// Store reference to object

const city = document.getElementById('Valdivia');


// Define event handler destructuring the nested event object

city.addEventListener('earthquake', function({detail: {type, scale}}) {
    console.log(type, scale);
});


// Dispatch event to target

city.dispatchEvent(earthquake);


In diesem Beispiel wird ein mit CustomEvent ein eigenes Ereignis definiert, das in der Folge auf einem bestimmten Element ausgelöst wird. Zuvor wird ein Eventhandler definiert, der beim Eintritt des Ereignisses aufgerufen wird. Der als Eventhandler registrierten Funktion wird bei ihrem Aufruf das Eventobjekt übergeben, dessen Eigenschaft detail wiederum ein Objekt enthält. Auch dieses Objekt wird destrukturiert und der Wert der Eigenschaften in die Konsole geschrieben.


Eigenschaft ist iterierbares Objekt

Ist der Wert einer Eigenschaft eines destrukturierten Objekts ein iterierbares Objekt, wie beispielsweise ein Array, ein Set oder eine Map, dann können die Einträge dieses Objekts ebenfalls über ein Destrukturierungsmuster referenziert werden. Das Muster wird einfach hinter dem entsprechenden Eigenschaftsnamen notiert.


Beispiel
// Define object with array property

const object = {
    array: [1, 2, 4, 8]
};


// Mixed object and array assignment pattern

let {array: [head, ...tail]} = object;


In dem Beispiel oben wird zunächst ein gewöhnliches Objekt definiert, dessen einzige eigene Eigenschaft eine Referenz auf ein Array enthält. Im nächsten Schritt wird das Objekt destrukturiert und auf die Eigenschaft array zugegriffen. Statt eine Bindung für die Eigenschaft zu erzeugen, wird unter Verwendung der Syntax für die Destrukturierung von iterierbaren Objekten das erste Element des Arrays in einer Variable mit dem Namen head hinterlegt. Die anderen Elemente des Arrays werden mittels Rest-Syntax aufgesammelt und an den Namen tail gebunden.


Hinweis:

Gemäß dem Fall, es handelt sich bei dem Wert einer Objekteigenschaft um ein Array, dessen Elemente selbst wieder Objekte sind, können auch diese Objekte wieder destrukturiert werden, indem an der gewünschten Position in der Liste ein entsprechender Destrukturierungsausdruck notiert wird.


Angabe von Standardwerten für einzelne Objekteigenschaften

Nicht immer ist sicher, dass eine Eigenschaft auf dem Objekt, das destrukturiert werden soll, auch definiert ist. Soll in einem solchen Fall ein Standardwert verwendet werden, kann dieser direkt bei der Destrukturierung angegeben werden. Die Syntax entspricht dabei der Notation von Standardwerten für Parameter, das heißt, es wird erst der Name der Objekteigenschaft angegeben, dann ein Gleichheitszeichen und schließlich der Standardwert.


Beispiel
// Object definition

const work = {
    title: 'Hackers',
    director: 'Iain Softley',
    year: 1995
};


// Object assignment pattern with default value

let {title, category = 'film'} = work;


In diesem Beispiel wird ein gewöhnliches Objekt destrukturiert und dabei auf zwei Eigenschaften zugegriffen. Das referenzierte Objekt besitzt jedoch keine Eigenschaft mit dem Namen category, was normalerweise dazu führen würde, dass als Ersatz der primitive Wert undefined an den angegebenen Bezeichner gebunden wird. Da hier jedoch ein Standardwert bereitgestellt wurde, wird stattdessen der hinter dem Eigenschaftsnamen notierte String in einer Variable hinterlegt.


Berechnete Eigenschaftsnamen

Ein Standardwert kann auch in Verbindung mit berechneten Eigenschaftsnamen verwendet werden. Auch in diesem Fall wird der Zuweisungsausdruck – also das Gleichheitszeichen und der Ausdruck, dessen Wert als Ersatz für eine undefinierte Eigenschaft des destrukturierten Objekts dient – hinter dem Bezeichner notiert, an den der Wert gebunden werden soll.


Beispiel
// Object definition

const film = {
    title: 'Tron',
    director: 'Steven Lisberger',
    year: 1982
};


// Computed property name with default value

let {title, ['DIRECTOR'.toLowerCase()]: director = 'unknown'} = film;


Wahl eines anderen Bezeichners

So wie bei der Verwendung von Standardwerten in Verbindung mit berechneten Eigenschaftsnamen wird auch verfahren, wenn der Eigenschaftswert an einen anderen Bezeichner als den Eigenschaftsnamen gebunden werden soll. Hier wird zunächst der Name der Eigenschaft notiert, dann ein Doppelpunkt, der neue Name und dann die übliche Syntax für den Standardwert.


Beispiel
// Object definition

const film = {
    title: 'The Matrix',
    directors: 'Lana and Lilly Wachowski',
    with: [
        'Keanu Reeves',
        'Laurence Fishburne',
        'Carrie-Anne Moss'
    ],
    year: 1999
};


// Default value assignment with different identifier

let {title, with: starring = []} = film;


Dabei spielt es keine Rolle, ob der Name der Objekteigenschaft grundsätzlich ein valider Bezeichner ist oder nicht, ob die Umbenennung also erforderlich ist oder nur dem Wunsch des Programmierers entspricht. Der Ausdruck für den Standardwert wird prinzipiell nach dem Bezeichner notiert, der letztlich das Ziel der Zuweisung sein soll, so wie in dem Beispiel oben.


Verschachtelte Objekte

Beispiel
// Object definition

const film = {
    title: 'WarGames',
    details: {
        director: 'John Badham',
        year: 1983
    }
};


// Default value assignment with nested object

let {title, details: {year = 'unknown'} = {}} = film;