Javascript, Objekte, Werte und Referenzen
Im Gegensatz zu einigen anderen Sprachen kopiert JavaScript bei einer Zuweisung lediglich bei der Verwendung primitiver Datenelemente den Wert der ursprünglichen Variablen. Bei allen anderen Datenstrukturen wird nur die Referenz kopiert, was zu unerwarteten und unerwünschten Ergebnissen führen kann.
var band = {
name : 'Deep Purple',
year : 1968,
members : {
vocals : 'Rod Evans',
guitar : 'Ritchie Blackmore'
}
}
Wird einer zweiten Variablen der Wert der ersten Variable zugewiesen, so wird intern keine Kopie der Werte erzeugt, sondern lediglich die Referenz auf die Werte kopiert. Dies führt dazu, daß bei einer Änderung von “band2” auch “band” geändert wird.
var band2 = band;
band2.year = 1969;
console.log(band);
{
"name": "Deep Purple",
"year": 1969,
"members": {
"vocals": "Rod Evans",
"guitar": "Ritchie Blackmore"
}
}
Lösungsmöglichkeit 1: Object.assign
Als erste Lösungsmöglichkeit kann “Object.assign” verwendet werden.
Hier wird eine Kopie des Objekts angelegt, die Ausgabe des Jahres ist nach der Änderung des Jahres weiterhin unverändert.
var band2 = Object.assign({}, band);
band2.year = 1969;
console.log(band);
{
"name": "Deep Purple",
"year": 1968,
"members": {
"vocals": "Rod Evans",
"guitar": "Ritchie Blackmore"
}
}
Allerdings ist zu beachten, daß lediglich die erste Ebene kopiert wird, da intern für “members” erneut eine Referenz verwendet wird.
band2.members.vocals = 'Ian Gillan';
console.log(band);
{
"name": "Deep Purple",
"year": 1968,
"members": {
"vocals": "Ian Gillan",
"guitar": "Ritchie Blackmore"
}
}
Lösungsmöglichkeit 2: spread
Die Verwendung der Spread-Syntax führt zum gleichen Ergebnis wie Object.assign.
var band2 = {...band};
band2.year = 1969;
band2.members.vocals = 'Ian Gillan';
console.log(band);
{
"name": "Deep Purple",
"year": 1968,
"members": {
"vocals": "Ian Gillan",
"guitar": "Ritchie Blackmore"
}
}
Lösungsmöglichkeit 3: JSON.stringify & JSON.parse
Das Erzeugen einer komplette Kopie kann erzwungen werden, wenn zum Kopieren explizit in die JavaScript Object Notation und wieder zurück gewandelt wird.
var band2 = JSON.parse(JSON.stringify(band));
band2.year = 1969;
band2.members.vocals = 'Ian Gillan';
console.log(band);
{
"name": "Deep Purple",
"year": 1968,
"members": {
"vocals": "Rod Evans",
"guitar": "Ritchie Blackmore"
}
}
Wer sich detaillierter mit der Thematik inklusive Lösungsansätzen für JQuery, AngularJS sowie Performance-Messungen auseinandersetzen möchte, dem sei ein Blick auf “How do I correctly clone a JavaScript object?” empfohlen.