Abschnitt 7 · Lektion 2
Eigenschaften ändern, hinzufügen, entfernen
Ein Objekt ist selten am Ende, wenn es fertig getippt ist. Werte ändern sich, Felder kommen dazu, andere fallen weg. Diese Lektion zeigt, wie das geht, und die wichtigste Aussage steht erst ganz am Ende.
Ändern und anlegen sind dieselbe Zeile
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> const kurs = { titel: "JavaScript", dauer: 47 };
console.log("Anfang:", kurs);
// Ein Schlüssel, den es gibt: der Wert wird ersetzt.
kurs.dauer = 50;
console.log("Nach der Änderung:", kurs);
// Ein Schlüssel, den es nicht gibt: er wird angelegt.
kurs.frei = true;
console.log("Nach dem Anlegen:", kurs);
// Mit eckigen Klammern geht beides genauso.
const feld = "sprache";
kurs[feld] = "Deutsch";
console.log("Mit Klammern:", kurs); Du schreibst den Zugriff auf die linke Seite eines Gleichheitszeichens, und der Rest ergibt sich: kurs.dauer = 50 ändert die Eigenschaft, wenn es sie gibt, und legt sie an, wenn es sie nicht gibt.
Dass beides dieselbe Schreibweise ist, ist bequem und hat einen Preis. Ein Tippfehler im Schlüssel bricht nicht ab, er legt still eine zweite Eigenschaft an: aus kurs.Dauer = 50 wird ein neues Feld neben dem alten, und niemand sagt etwas.
Mit eckigen Klammern funktioniert es genauso, mit derselben Bedeutung wie beim Lesen aus Lektion 7.1. Damit kannst du eine Eigenschaft setzen, deren Name erst zur Laufzeit feststeht.
Weg ist nicht gleich weg
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> const a = { titel: "JavaScript", dauer: 47 };
const b = { titel: "JavaScript", dauer: 47 };
// Links: der Wert wird undefined, der Schlüssel bleibt.
a.dauer = undefined;
// Rechts: der Schlüssel verschwindet wirklich.
delete b.dauer;
// Beim Auslesen sieht das gleich aus.
console.log("a.dauer:", a.dauer);
console.log("b.dauer:", b.dauer);
// Mit in wird der Unterschied sichtbar.
console.log("in a:", "dauer" in a);
console.log("in b:", "dauer" in b);
// Und die Schlüsselliste zeigt ihn auch.
console.log("Schlüssel von a:", Object.keys(a));
console.log("Schlüssel von b:", Object.keys(b)); Es gibt zwei Arten, eine Eigenschaft loszuwerden, und sie tun Verschiedenes.
obj.dauer = undefined setzt den Wert auf undefined. Der Schlüssel bleibt, das Objekt hat weiterhin ein Feld namens dauer, es steht nur nichts mehr drin. delete obj.dauer entfernt den Schlüssel und damit die Eigenschaft selbst.
Beim einfachen Auslesen siehst du keinen Unterschied, beide liefern undefined. Der Unterschied wird erst mit dem in-Operator sichtbar: "dauer" in a fragt, ob es den Schlüssel gibt, und nicht, was drinsteht. Dieselbe Auskunft gibt Object.keys, das dir alle Schlüssel als Liste zurückgibt und in Lektion 7.7 die Hauptrolle spielt.
In der Praxis nimmt man delete selten. Meistens baut man sich ein neues Objekt ohne das Feld, und wie das geht, steht in Lektion 7.6. Wissen musst du den Unterschied trotzdem, denn er erklärt, warum ein Objekt manchmal einen Schlüssel führt, den scheinbar niemand gesetzt hat.
Warum const hier nichts verbietet
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> const kurs = { titel: "JavaScript" };
// Das geht, obwohl kurs ein const ist.
kurs.titel = "CSS";
kurs.dauer = 30;
console.log("Verändert:", kurs);
// Das geht nicht. Diese Zeile steht deshalb ganz unten,
// sonst käme der Rest nicht mehr dran.
kurs = { titel: "Etwas ganz anderes" };
console.log("Diese Zeile wird nie erreicht"); Das ist die Stelle, an der viele stutzen. const kurs = { ... } und trotzdem lässt sich kurs.titel ändern. Ist const also wirkungslos?
Nein, es meint nur etwas anderes, als man beim ersten Lesen denkt. const legt fest, worauf der Name zeigt, nicht was dort liegt. Der Name kurs zeigt auf ein bestimmtes Objekt, und das bleibt so. Das Objekt selbst darf sich beliebig verändern.
Am Ende des Beispiels steht deshalb der Fall, den const wirklich verhindert: eine neue Zuweisung an den Namen. Sie wirft einen TypeError mit dem Text „Assignment to constant variable” (Firefox: „invalid assignment to const”), und wie jeder Fehler beendet sie das Skript an dieser Stelle. Genau deshalb steht sie im Beispiel ganz unten.
Wer ein Objekt wirklich einfrieren will, nimmt Object.freeze. Das kommt im Kurs nicht wieder vor, aber der Name lohnt sich zu kennen.
Die wichtigste Zeile dieser Lektion
<h1>Ausgabe</h1>
<p>Was dieses Beispiel tut, steht in der Console.</p> // Bei einer Zahl passiert nichts draußen.
function erhoehe(zahl) {
zahl = zahl + 1;
}
let punkte = 10;
erhoehe(punkte);
console.log("Punkte draußen:", punkte);
// Bei einem Objekt schon.
function markiereAlsFertig(eintrag) {
eintrag.fertig = true;
}
const aufgabe = { titel: "Objekte üben" };
markiereAlsFertig(aufgabe);
console.log("Aufgabe draußen:", aufgabe);
// Auch wenn der Parameter anders heißt als die Variable.
// Der Name ist neu, das Objekt dahinter ist dasselbe. Übergibst du eine Zahl an eine Funktion, bekommt sie eine Kopie. Ändert sie den Parameter, merkt draußen niemand etwas. Das kennst du aus Abschnitt 5 und es fühlt sich richtig an.
Bei einem Objekt ist es anders: die Funktion arbeitet auf demselben Objekt. Sie bekommt keinen Nachbau, sondern einen zweiten Namen für dasselbe Ding. Ändert sie eine Eigenschaft, ist die Änderung draußen sichtbar, und zwar sofort.
Das ist nützlich und es ist die häufigste Quelle für Fehler, die man stundenlang sucht. Eine Funktion, die still ein Objekt verändert, das ihr nur zum Lesen gegeben wurde, hinterlässt Spuren an einer Stelle, an der niemand nachschaut.
Der Ausweg heißt: nicht verändern, sondern eine geänderte Kopie zurückgeben. Wie man die baut, ist Lektion 7.6, und dort steht auch, warum das inzwischen das übliche Vorgehen ist.
Zum Mitnehmen
Eine Funktion, die ein Objekt bekommt, arbeitet nicht auf einer Kopie. Sie arbeitet auf demselben Objekt, und ihre Änderungen sind draußen sichtbar.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
Was in dieser Lektion steckt
-
Artikel mit 4 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe im Editor, direkt im Browser geprüft
Öffnet sich mit dem Basis Konto.