- Lernen
- Informatik & Informationswissenschaften
- Programmierung
- JavaScript – DOM, Ereignisse und asynchroner Code
- Objekte und JSON in JavaScript
Daten modellieren: Objekte und JSON in JavaScript
AnfängerEinheit 4 von 9 in Kurs: JavaScript – DOM, Ereignisse und asynchroner Code
Was du lernst
- Beschreibe reale Dinge im Code als Objekte mit benannten Eigenschaften, lies und ändere diese Eigenschaften und verstehe, wie Objekte gespeichert, kopiert und verglichen werden.
- Erstelle Objekte und arbeite mit ihren EigenschaftenSchreibe Objektliterale, lies Eigenschaften mit Punkt- und Klammernotation und füge Eigenschaften hinzu, ändere und lösche sie.
- Prüfe und durchlaufe die Eigenschaften eines ObjektsPrüfe, ob eine Eigenschaft existiert, liste Schlüssel, Werte und Schlüssel-Wert-Paare auf und durchlaufe oder transformiere die Eigenschaften eines Objekts.
- Verstehe Referenzen, Kopieren und VergleichenErkläre, warum Objekte über Referenzen gemeinsam genutzt werden, vergleiche Objekte richtig und erstelle flache und tiefe Kopien.
- Arbeite mit verschachtelten DatenLies und verarbeite Objekte innerhalb von Objekten und Arrays aus Objekten, fange fehlende Teile mit ?. und ?? ab und wähle eine Struktur, die zu den Daten passt.
- Erstelle Objekte und arbeite mit ihren Eigenschaften
- Schreibe Methoden, die auf die Daten ihres Objekts zugreifen, erkläre, wie der Wert des Schlüsselworts this bei den verschiedenen Aufrufarten bestimmt wird, und behalte den richtigen Wert von this bei, wenn eine Methode weitergegeben wird.
- Schreibe Methoden, die auf die Daten ihres Objekts zugreifenDefiniere Methoden mit der Kurzschreibweise, lies und aktualisiere das Objekt mit this und rufe Methoden richtig auf.
- Erkläre, wie der Wert von this bestimmt wirdBestimme den Wert von this anhand der Art, wie eine Funktion aufgerufen wird, und erkläre, warum sich Pfeilfunktionen anders verhalten.
- Behalte den Wert von this bei, wenn du Methoden als Callbacks übergibstErkenne, wann eine Methode ihr Objekt verliert, und behebe das mit einem Pfeilfunktions-Wrapper, bind, call oder apply.
- Schreibe Methoden, die auf die Daten ihres Objekts zugreifen
- Hole Werte mit Destrukturierung aus Objekten und Arrays und kopiere, kombiniere und sammle Werte mit der Spread- und Rest-Syntax.
- Destrukturiere ObjekteEntpacke Objekteigenschaften in Variablen, mit Umbenennung, Standardwerten, verschachtelten Mustern und destrukturierten Funktionsparametern.
- Destrukturiere Arrays und andere iterierbare ObjekteEntpacke Werte anhand ihrer Position, überspringe sie oder lege Standardwerte fest, vertausche Variablen und destrukturiere Schlüssel-Wert-Paare in Schleifen.
- Kopiere, führe zusammen und sammle mit Spread und RestKopiere und kombiniere Objekte und Arrays mit Spread und übergib Arrayelemente als Argumente, sammle Werte mit Rest und unterscheide die beiden.
- Destrukturiere Objekte
- Verwende Map für Schlüssel-Wert-Sammlungen mit Schlüsseln beliebigen Typs und Set für Sammlungen eindeutiger Werte und wähle zwischen ihnen und einfachen Objekten und Arrays.
- Speichere Schlüssel-Wert-Paare in einer MapErstelle und aktualisiere eine Map, durchlaufe ihre Einträge, wandle Maps in Objekte und Objekte in Maps um und entscheide, wann eine Map besser passt als ein Objekt.
- Speichere eindeutige Werte in einem SetErstelle und aktualisiere ein Set, entferne Duplikate aus Arrays und vergleiche Sammlungen mit Mengenoperationen.
- Speichere Schlüssel-Wert-Paare in einer Map
- Lies und schreibe das JSON-Textformat, wandle JavaScript-Werte mit JSON.stringify in JSON und JSON-Text mit JSON.parse zurück in Werte um und behandle die Fälle, in denen beides nicht übereinstimmt.
- Lies und schreibe Daten im JSON-FormatErkenne gültiges JSON, erkläre, wie es sich von einem JavaScript-Objektliteral unterscheidet, und finde häufige Syntaxfehler.
- Wandle Werte mit JSON.stringify in JSON-Text umWandle Objekte und Arrays in JSON-Zeichenketten um, formatiere die Ausgabe, wähle die aufzunehmenden Eigenschaften und sage voraus, was weggelassen oder geändert wird.
- Wandle JSON-Text mit JSON.parse in Werte umParse JSON sicher, stelle Werte wie Datumsangaben mit einer Reviver-Funktion wieder her, prüfe die geparsten Daten und führe einen Roundtrip von Daten durch JSON aus.
- Lies und schreibe Daten im JSON-Format
Objekte und JSON in JavaScript einfach erklärt
1Modelliere Daten mit Objekten
Ein Objekt hält zusammengehörige Werte unter Namen zusammen, sodass ein Datensatz ein Buch, eine Person oder eine Messung beschreiben kann. Mithilfe dieser Namen kannst du ein Feld ändern, einen ganzen Datensatz untersuchen und Listen von Datensätzen organisieren. Außerdem verfolgst du, welche Variablen auf dasselbe Objekt verweisen. Dieser Unterschied ist wichtig, wenn eine Änderung an zwei Stellen erscheint, eine Kopie verschachtelte Daten enthält oder ein fehlendes Feld einen sinnvollen Standardwert benötigt.
1.1 Erstelle Objekte und arbeite mit ihren Eigenschaften
Ein Objekt fasst zusammengehörige Werte unter Namen zusammen. Jede Eigenschaft ordnet einem Schlüssel einen Wert zu. Verwende ein Objekt für einen Datensatz und ein Array aus Objekten für eine geordnete Liste. Parallele Arrays können ihre Zuordnung verlieren, wenn nur eines sortiert oder geändert wird.
Einen Datensatz erstellen und lesen
const book = { title: "Dune", pages: 412, available: true };
book.title; // "Dune"
book["title"]; // "Dune"
Eigenschaftswerte können neben primitiven Werten auch Arrays, Objekte oder Funktionen sein. Schlüssel sind Zeichenketten oder Symbole; diese Beispiele verwenden Zeichenketten. Zeichenkettenschlüssel, die gültige Bezeichner sind, brauchen keine Anführungszeichen. Schlüssel mit Leerzeichen oder Bindestrichen brauchen Anführungszeichen: { "release-year": 1965 }. Numerische Schlüssel werden zu Zeichenketten, daher hat { 1: "a" } den Schlüssel "1". Objektliterale erlauben ein abschließendes Komma.
Der Zugriff mit Punkt verwendet den wörtlichen Namen nach dem Punkt. Der Zugriff mit eckigen Klammern wertet einen Ausdruck aus:
const field = "pages";
book[field]; // 412
book.field; // undefined
Der zweite Ausdruck sucht nach einer Eigenschaft namens "field". Eckige Klammern ermöglichen auch book["release-year"]. Eine fehlende Eigenschaft liefert undefined; ein weiterer Zugriff darauf, wie in book.author.name, löst einen TypeError aus, wenn author fehlt.
Den Inhalt des Objekts ändern
book.author = "Frank Herbert";
book.pages = 896;
delete book.available;
Eine Zuweisung fügt eine fehlende Eigenschaft hinzu oder ersetzt einen vorhandenen Wert. Das Löschen entfernt die Eigenschaft selbst, sodass "available" in book nun falsch ist. const hält die Variable an dieses Objekt gebunden, erlaubt aber Änderungen an dessen Inhalt.
Für const reading = { city: "Nairobi", tempC: 24.5 }; speichert reading.tempC += 1.5; den Wert 26. Dann fügt reading.humidity = 61; ein Feld hinzu. Mit const key = "humidity"; liest reading[key] den Wert 61. Ein Name wie tempC macht die Einheit der Messung sichtbar.
Variablen in einem Literal verwenden
const name = "Lena";
const age = 29;
const person = { name, age };
const lang = "nl";
const greeting = { [lang]: "Hallo" };
Die Kurzschreibweise { name, age } bedeutet { name: name, age: age }. Ein berechneter Name wertet den Ausdruck innerhalb der eckigen Klammern aus: greeting hat die Eigenschaft "nl". Ohne diese Klammern würde { lang: "Hallo" } den wörtlichen Schlüssel "lang" erstellen.
Wichtige Erkenntnisse
- Ein Objekt fasst zusammengehörige Werte in benannten Eigenschaften zusammen.
- Verwende eckige Klammern für einen in einer Variablen gespeicherten Schlüssel oder einen Schlüssel mit Bindestrich.
- Eine Zuweisung fügt eine Eigenschaft hinzu oder ersetzt sie;
deleteentfernt sie. constlegt die Variable fest, nicht den Inhalt des Objekts.- Die Kurzschreibweise übernimmt einen Variablenwert; ein berechneter Schlüssel wertet einen Ausdruck aus.
1.2 Prüfe und durchlaufe die Eigenschaften eines Objekts
Zu prüfen, ob ein Feld existiert, ist etwas anderes, als seinen Wert zu prüfen. Eine leere Zeichenkette, null oder false kann ein durchaus gültiger gespeicherter Wert sein.
Die richtige Frage nach der Existenz stellen
const item = { stock: 0, note: undefined };
Object.hasOwn(item, "stock"); // true
"note" in item; // true
Boolean(item.stock); // false
Object.hasOwn(obj, key) prüft nur die eigenen Eigenschaften des Objekts. Der Operator in prüft auch geerbte Eigenschaften: "toString" in {} ist true, während Object.hasOwn({}, "toString") gleich false ist. Älterer Code ruft häufig obj.hasOwnProperty(key) auf.
Eine Bedingung wie if (item.stock) prüft, ob der Wert truthy ist. Sie kann ein fehlendes Feld nicht von einem vorhandenen Feld mit dem Wert null unterscheiden. Dasselbe Problem gilt für "", false, null, undefined und NaN. Selbst der Wert undefined kann zu einer vorhandenen Eigenschaft gehören, wie oben bei note.
Schlüssel, Werte oder Paare wählen
Für const scores = { Ana: 82, Ben: 74, Chen: 91 }; geben diese Funktionen Arrays der eigenen aufzählbaren Eigenschaften mit Zeichenkettenschlüsseln zurück:
| Ausdruck | Ergebnis |
|---|---|
Object.keys(scores) | ["Ana", "Ben", "Chen"] |
Object.values(scores) | [82, 74, 91] |
Object.entries(scores) | [["Ana", 82], ["Ben", 74], ["Chen", 91]] |
Das Objekt hat keine Länge wie ein Array: scores.length ist undefined. Object.keys(scores).length zählt drei Eigenschaften. Um die Punktzahlen zu summieren, reduziere die Werte mit null als Anfangswert. Ihre Summe ist 247 und ihr Mittelwert etwa 82,33.
Mit beiden Teilen eine Schleife durchlaufen
let bestName;
let bestScore = -Infinity;
for (const [name, score] of Object.entries(scores)) {
if (score > bestScore) {
bestName = name;
bestScore = score;
}
}
Die Schleife vergleicht 82, 74 und dann 91 mit der bisher höchsten Punktzahl. Am Ende stehen "Chen" und 91. Das Muster mit eckigen Klammern gibt den beiden Teilen jedes Paars Namen.
Ein einfaches Objekt ist nicht iterierbar, daher löst for...of scores einen TypeError aus. Object.entries(scores) liefert ein iterierbares Array. Die ältere for...in-Schleife liefert Zeichenkettenschlüssel und kann geerbte aufzählbare Eigenschaften einschließen.
Einträge zurück in ein Objekt umwandeln
const weightsG = { flour: 500, sugar: 250, salt: 5 };
const weightsKg = Object.fromEntries(
Object.entries(weightsG).map(([item, g]) => [item, g / 1000])
);
entries erzeugt Paare, map ändert jeden Wert und behält seinen Schlüssel bei, und fromEntries erstellt den Datensatz erneut. Das Ergebnis ist { flour: 0.5, sugar: 0.25, salt: 0.005 }; weightsG bleibt unverändert.
Die Reihenfolge eigener Eigenschaften ist festgelegt. Arrayindexschlüssel von "0" bis "4294967294" erscheinen zuerst in aufsteigender Reihenfolge; andere Zeichenkettenschlüssel folgen in Einfügereihenfolge. Eine führende Null wie in "01" verhindert, dass ein Schlüssel ein Arrayindex ist. Daher ergibt Object.keys({ b: 1, 2: "x", a: 2, 1: "y" }) den Wert ["1", "2", "b", "a"]. Verwende ein Array, wenn die Positionen eine Bedeutung haben.
Wichtige Erkenntnisse
- Die Existenz einer Eigenschaft und ihr Wahrheitswert beantworten unterschiedliche Fragen.
Object.hasOwnprüft eigene Eigenschaften;inprüft auch geerbte.Object.entriesliefert Schlüssel-Wert-Paare für Schleifen und Transformationen.Object.fromEntrieserstellt aus Paaren wieder ein Objekt.- Arrayindexschlüssel stehen in der Eigenschaftsreihenfolge vor anderen Zeichenkettenschlüsseln.
- Zähle eigene aufzählbare Zeichenkettenschlüssel mit
Object.keys(obj).length.
1.3 Verstehe Referenzen, Kopieren und Vergleichen
Zwei Variablen können auf ein Objekt verweisen. Bevor du eine Aktualisierung vorhersagst, entscheide, ob der Code ein neues Objekt erstellt oder eine Referenz auf ein vorhandenes Objekt kopiert hat.
Identität und Daten getrennt verfolgen
const p1 = { x: 1 };
const p2 = p1;
p2.x = 99;
p1.x; // 99
p1 === p2; // true
Die Zuweisung hat die Referenz kopiert. Beide Namen führen zur selben Eigenschaft. Die Zuweisung primitiver Werte funktioniert anders: Nach let a = 5; let b = a; b = 6; bleibt a gleich 5.
Objekte werden sowohl mit === als auch mit == anhand ihrer Identität verglichen. Zwei Literale erstellen getrennte Objekte, selbst wenn alle Felder übereinstimmen: ({ x: 1 } === { x: 1 }) ist false. Um ihre Daten zu vergleichen, vergleiche die relevanten Eigenschaften. Eine übereinstimmende Darstellung bei der Ausgabe ist keine Identitätsprüfung.
Auch die Übergabe eines Objekts an eine Funktion kopiert seine Referenz. Eine Funktion, die order.status = "shipped"; ausführt, ändert das Objekt des Aufrufers. Gibt sie stattdessen { ...order, status: "shipped" } zurück, erstellt sie einen neuen Datensatz auf der obersten Ebene.
const, Einfrieren und Kopieren unterscheiden
const cart = { items: 2 }; erlaubt cart.items = 3;, aber die Neuzuweisung cart = {}; löst einen TypeError aus. Object.freeze(cart) verhindert Änderungen an den eigenen Eigenschaften des Objekts. Im strikten Modus lösen Versuche, sie hinzuzufügen, zu entfernen oder zu überschreiben, einen TypeError aus.
Das Einfrieren ist flach. Enthält ein eingefrorener Datensatz ein weiteres Objekt, können die Felder dieses verschachtelten Objekts weiterhin geändert werden. Ein eingefrorener Behälter und eine bis in die Tiefe unveränderliche Struktur sind verschiedene Dinge.
Eine flache Kopie verfolgen
const settings = { theme: "dark", font: { size: 14 } };
const copy = { ...settings };
copy.theme = "light";
copy.font.size = 18;
Spread erstellt ein neues äußeres Objekt. Sein theme-Wert wird kopiert, sodass eine Änderung von copy.theme den Wert von settings.theme bei "dark" belässt. Sein font-Wert ist eine Referenz, die in beide Datensätze kopiert wird. Eine Aktualisierung von copy.font.size setzt daher auch settings.font.size auf 18.
Auch Object.assign({}, settings) erstellt eine flache Kopie. Eine flache Kopie trennt den äußeren Datensatz ab, während die Identität verschachtelter Objekte und Arrays erhalten bleibt.
Verschachtelte Daten kopieren, wenn sie unabhängig sein müssen
const deep = structuredClone(settings);
deep.font.size = 22;
settings.font.size; // 18
structuredClone kopiert verschachtelte Objekte und Arrays sowie unterstützte Werte wie Map, Set und Date. Es verarbeitet auch zirkuläre Referenzen. Das neue verschachtelte font kann unabhängig geändert werden. Funktionen lassen sich auf diese Weise nicht klonen: Ein Objekt mit einer Methode verursacht einen DataCloneError.
Ein JSON-Roundtrip, JSON.parse(JSON.stringify(obj)), kopiert nur JSON-kompatible Daten. Er lässt Objekteigenschaften mit undefined oder Funktionen weg, wandelt Datumswerte in Zeichenketten um und verliert Einträge von Maps und Sets, sofern du sie nicht umwandelst. Wähle einen Klon für unabhängige unterstützte JavaScript-Daten und JSON, wenn du eine Textdarstellung erstellen möchtest.
Wichtige Erkenntnisse
- Zuweisungen und Funktionsaufrufe kopieren Objektreferenzen.
- Objekte werden anhand ihrer Identität verglichen, auch wenn ihre Felder übereinstimmen.
- Eine flache Kopie nutzt verschachtelte Objekte gemeinsam mit dem Original.
Object.freezeverhindert Änderungen an eigenen Eigenschaften, wirkt aber nur flach.structuredClonekopiert unterstützte verschachtelte Daten und lehnt Funktionen ab.
1.4 Arbeite mit verschachtelten Daten
Verschachtelte Daten kombinieren Datensätze und Listen. Lies einen Pfad Schritt für Schritt und prüfe, ob jeder Schritt zu einem Objekt, einem Array oder einem endgültigen Wert führt.
Eine Liste innerhalb eines Datensatzes lesen und verarbeiten
const order = {
id: 1042,
customer: { name: "Sara", city: "Lisbon" },
items: [
{ product: "Tea", qty: 2, unitPrice: 4.5 },
{ product: "Mug", qty: 1, unitPrice: 9 }
]
};
order.customer.city liest "Lisbon". order.items[1].product wählt zuerst das items-Array, dann dessen zweiten Datensatz und schließlich "Mug" aus. order.items.length ist 2.
Die bereits bekannten Arraymethoden arbeiten mit Datensatzeigenschaften. map(item => item.product) erzeugt Produktnamen. filter(item => item.qty > 1) behält die Teeposition. find(item => item.product === "Mug") gibt den vorhandenen Tassendatensatz zurück. Änderst du diesen zurückgegebenen Datensatz, änderst du auch die Position in der Bestellung.
Um den Gesamtbetrag zu berechnen, verwende order.items.reduce((sum, item) => sum + item.qty * item.unitPrice, 0). Die erste Position addiert 9; die zweite addiert weitere 9, sodass 18 entsteht. Berechnest du den Gesamtbetrag bei Bedarf, verhinderst du, dass ein separat gespeicherter Gesamtbetrag nach einer Änderung der Positionen veraltet.
Optionale Daten mit einer Rückfalllösung lesen
order.shipping?.date; // undefined
order.customer?.city ?? "unknown"; // "Lisbon"
Die optionale Verkettung ?. bricht ab, wenn der Wert unmittelbar links davon null oder undefined ist. Ein direkter Zugriff mit order.shipping.date würde einen TypeError auslösen. Verwende an jedem optionalen Glied eines längeren Pfads eine Prüfung. Auch der Zugriff mit eckigen Klammern und Aufrufe unterstützen dies: order.items?.[0] und order.print?.().
Die optionale Verkettung ist für Werte gedacht, die fehlen dürfen. Für Pflichtfelder brauchst du weiterhin Prüfungen oder Fehler, die einen fehlerhaften Datensatz sichtbar machen. Sie kann nicht links von einer Zuweisung stehen: order.shipping?.date = "2026-05-01" ist ein Syntaxfehler.
Der Nullish-Coalescing-Operator ?? verwendet seine rechte Seite nur bei null oder undefined. Er behält null, false und "" bei. Für const qty = 0; bleibt qty ?? 1 gleich null, während qty || 1 zu 1 wird, weil || jeden Falsy-Wert ersetzt.
Eine geeignete Struktur wählen
Ein Array aus Datensätzen eignet sich zum Auflisten, Filtern und Ordnen. Ein Objekt mit IDs als Schlüsseln ermöglicht einen direkten Zugriff: usersById["u23"].name. Eine Map ist nützlich, wenn Suchschlüssel häufig hinzugefügt und entfernt werden.
Neueres JavaScript bietet Object.groupBy, das seit 2024 breit verfügbar ist:
const tasks = [
{ title: "Book flights", status: "done" },
{ title: "Pack", status: "todo" },
{ title: "Renew passport", status: "done" }
];
const grouped = Object.groupBy(tasks, task => task.status);
grouped.done enthält zwei Datensätze und grouped.todo einen. Das Ergebnis hat keinen Prototyp und daher keine geerbte toString-Methode. Eine ältere Alternative erstellt die Arrays für diese Statusschlüssel ausdrücklich:
const groupedOlder = tasks.reduce((groups, task) => {
if (!Object.hasOwn(groups, task.status)) {
groups[task.status] = [];
}
groups[task.status].push(task);
return groups;
}, {});
Der erste Datensatz jeder Gruppe erstellt ihr Array. Spätere Datensätze werden an dasselbe Array angehängt. Dieser Akkumulator ist ein gewöhnliches Objekt; das Ergebnis der neueren Methode hat keinen Prototyp. Verwende einheitliche Namen und Werttypen in allen Datensätzen; Namen wie distanceKm und tempC halten außerdem die Einheiten sichtbar.
Wichtige Erkenntnisse
- Lies einen verschachtelten Pfad vom äußeren Objekt zum benötigten Wert.
findgibt den vorhandenen Datensatz zurück, keine Kopie.?.bricht bei null oder undefined ab;??liefert dafür eine Rückfalllösung.- Verwende ein Array für eine geordnete Liste und Daten mit Schlüsseln für den direkten Zugriff.
Object.groupBygruppiert Datensätze unter Schlüsseln in Arrays.- Einheitliche Feldnamen, Typen und Einheiten erleichtern die Verarbeitung von Datensätzen.
2Gib Objekten mit Methoden und this ein Verhalten
Methoden ermöglichen es einem Objekt, seine Daten mit Aktionen zu verbinden, die diese Daten nutzen. Das kleine Wort this verbindet eine Aktion mit einem Objekt, doch sein Wert hängt davon ab, wie die Funktion ausgeführt wird. Du verfolgst gewöhnliche Methodenaufrufe, entliehene Methoden und Callbacks und wählst dann einen Wrapper oder eine gebundene Funktion, wenn eine Aktion ihr Objekt behalten muss. Die Beispiele laufen als Module, daher gilt der strikte Modus, sofern ein Beispiel nicht ausdrücklich nicht strikten Code verwendet.
2.1 Schreibe Methoden, die auf die Daten ihres Objekts zugreifen
Eine Methode ist eine Eigenschaft, deren Wert eine Funktion ist und die über ein Objekt aufgerufen wird. Sie ermöglicht einer Aktion, die aktuellen Daten des Datensatzes zu nutzen.
Eine Methode mit this schreiben
const counter = {
count: 0,
increment() {
this.count += 1;
return this.count;
}
};
counter.increment(); // 1
counter.increment(); // 2
Die Kurzschreibweise increment() { ... } definiert eine Eigenschaft, deren Wert eine reguläre Funktion ist. In counter.increment() wird das Empfängerobjekt counter zu this. Jeder Aufruf liest den gespeicherten Zählerstand, addiert eins und gibt die neue Zahl zurück.
Ein allein stehendes count wählt eine Variable, nicht die Eigenschaft. Ohne passende Variable löst count += 1 einen ReferenceError aus. Verwende this.count, um auf das Feld des Empfängerobjekts zuzugreifen.
Eine Funktion lesen oder ausführen
counter.increment liest einen Wert vom Typ "function". Die Klammern in counter.increment() führen die Funktion aus und liefern ihren Rückgabewert. Wenn du eine Aktion zur späteren Verwendung übergibst, benötigt der empfangende Code die Funktion, nicht das Ergebnis ihrer sofortigen Ausführung.
Auch integrierte Methoden verwenden diese Aufrufform: Math.max(3, 7) gibt 7 und "abc".toUpperCase() gibt "ABC" zurück.
Eine Aktion wiederverwenden
function describe() {
return this.name + " (" + this.year + ")";
}
const film = { name: "Up", year: 2009, describe };
const song = { name: "Hello", year: 2015, describe };
film.describe() gibt "Up (2009)" zurück; song.describe() gibt "Hello (2015)" zurück. Mit this kann dieselbe Funktion beide Empfängerobjekte lesen. Ein fest geschriebenes film.name würde sie an die Variable film binden.
Das Empfängerobjekt für eine weitere Aktion zurückgeben
const playlist = {
tracks: [],
add(title) { this.tracks.push(title); return this; },
count() { return this.tracks.length; }
};
playlist.add("Rain").add("Waves").count(); // 2
Jeder add-Aufruf gibt die Wiedergabeliste zurück, sodass die nächste Methode auf diesem Objekt gesucht werden kann. Würde add eine Zahl zurückgeben, bräche die Kette ab, weil das nächste add auf dieser Zahl gesucht würde.
Die gewöhnliche JSON-Umwandlung lässt Methoden weg: Beim Umwandeln von { name: "Kit", hi() { return 1; } } in eine JSON-Zeichenkette wird nur name geschrieben. Das Parsen kann weggelassenen Code nicht wiederherstellen. Datensätze zum Speichern oder Austauschen enthalten häufig einfache Daten und verwenden separate Verarbeitungsfunktionen.
Wichtige Erkenntnisse
- Eine Methode ist eine Eigenschaft, deren Wert eine Funktion ist und die über ein Objekt aufgerufen wird.
- In
obj.method()verwendet eine reguläre Methodeobjalsthis. - Ein Funktionswert und das Ergebnis seines Aufrufs sind verschiedene Werte.
- Die Rückgabe von
thiskann einen weiteren Methodenaufruf ermöglichen. - Die gewöhnliche JSON-Umwandlung lässt Eigenschaften weg, deren Wert eine Funktion ist.
2.2 Erkläre, wie der Wert von this bestimmt wird
Bei einer regulären Funktion bestimmt der Aufruf this. Das Speichern einer Funktion in einem Objekt bindet sie nicht dauerhaft an dieses Objekt.
Das Empfängerobjekt beim Aufruf verfolgen
const a = { n: "A", who() { return this.n; } };
const b = { n: "B" };
b.who = a.who;
a.who(); // "A"
b.who(); // "B"
Beide Eigenschaften enthalten dieselbe Funktion. Das Empfängerobjekt vor dem Punkt ist unterschiedlich, daher unterscheiden sich die Ergebnisse. Der ursprüngliche Ort der Funktion entscheidet nicht, welches Objekt sie liest.
Bei einem einfachen Aufruf f() liefert der strikte Modus undefined als this. JavaScript-Module laufen immer im strikten Modus; auch ein Skript oder eine Funktion kann mit "use strict"; beginnen. Eine nicht strikte reguläre Funktion, die einfach aufgerufen wird, verwendet stattdessen das globale Objekt globalThis. In einem Browser ist dieses globale Objekt window.
Den umgebenden Kontext einer Pfeilfunktion erkennen
Eine Pfeilfunktion hat kein eigenes this. Sie behält das this des umgebenden Codes, in dem sie erstellt wurde. Ein Objektliteral erzeugt keinen neuen this-Kontext.
// At the top level of a module:
const user = {
name: "Ida",
hi: () => "Hi, " + this.name
};
Der Aufruf von user.hi() löst einen TypeError aus: Die Pfeilfunktion hat das this der obersten Modulebene übernommen, das gleich undefined ist. Auch wenn der Aufruf wie ein Methodenaufruf aussieht, erhält die Pfeilfunktion dadurch kein neues Empfängerobjekt. Auf der obersten Ebene eines klassischen Skripts ist das umgebende this stattdessen das globale Objekt.
Verwende eine reguläre Methode, wenn die Aktion das aufrufende Objekt benötigt. Verwende eine Pfeilfunktion innerhalb dieser Methode, wenn ein Callback den Kontext der Methode behalten muss:
const group = {
title: "Team",
members: ["Ana", "Ben"],
list() {
return this.members.map(m => this.title + ": " + m);
}
};
group.list(); // ["Team: Ana", "Team: Ben"]
list erhält group durch seinen Methodenaufruf. Die Pfeilfunktion wird innerhalb dieser laufenden Methode erstellt und behält dasselbe this. Einem strikten regulären Callback ohne übergebenes Empfängerobjekt würde undefined zugewiesen, sodass this.title dort fehlschlagen würde.
Eine Entscheidungsreihenfolge verwenden
Wenn du einem Aufruf begegnest, bestimme zuerst die aufgerufene Funktion:
- Eine Pfeilfunktion behält ihr umgebendes
this;call,applyundbindkönnen es nicht ersetzen. - Eine gebundene reguläre Funktion behält ihr gebundenes
this, auch beicalloderapply. - Eine ungebundene reguläre Funktion, die mit
calloderapplyaufgerufen wird, verwendet das übergebenethis. - Ein gewöhnlicher Aufruf
obj.method()verwendetobj. - Ein einfacher regulärer Aufruf verwendet im strikten Modus
undefinedoder im nicht strikten Modus das globale Objekt.
Callbacks können von ihrem Aufrufer ein Empfängerobjekt erhalten. Ein regulärer DOM-Event-Listener, der mit addEventListener registriert wird, erhält beispielsweise das Element, an dem er registriert ist, als this. Lies nach, wie der empfangende Code einen Callback aufruft, bevor du von einem einfachen Aufruf ausgehst.
Wichtige Erkenntnisse
- Eine reguläre Funktion erhält
thisdurch ihren Aufruf; wird eine Methode entliehen, ändert sich daher ihr Empfängerobjekt. - Ein einfacher Aufruf im strikten Modus verwendet
undefinedalsthis. - Eine Pfeilfunktion behält das umgebende
thisder Stelle, an der sie erstellt wurde. - Ein gebundenes Empfängerobjekt hat Vorrang vor einem späteren
calloderapply. - Eine Pfeilfunktion innerhalb einer regulären Methode kann das
thisdieser Methode behalten.
2.3 Behalte den Wert von this bei, wenn du Methoden als Callbacks übergibst
Wird eine Methode aus ihrem Objekt herausgelöst, bleibt die Funktion erhalten, aber der ursprüngliche Aufrufausdruck geht verloren. Ein Callback muss so aufgerufen werden, dass er das benötigte Objekt erhält.
Eine losgelöste Methode untersuchen
const counter = {
count: 0,
increment() {
this.count += 1;
return this.count;
}
};
const inc = counter.increment;
inc(); // TypeError in strict mode
inc() ist ein einfacher Aufruf, daher ist this gleich undefined. Das Lesen von this.count schlägt fehl, bevor eine Erhöhung stattfinden kann. In nicht striktem Code verwendet ein einfacher Aufruf das globale Objekt und schreibt möglicherweise stattdessen ein globales count; er greift nicht auf den Zähler zu.
Dasselbe Problem tritt bei Array-Callbacks auf. [1, 2].map(counter.increment) übergibt eine Funktion ohne ihr ursprüngliches Empfängerobjekt an map. Die als Argumente übergebenen Arraywerte liefern kein this.
Den Methodenaufruf umschließen
const results = [1, 2].map(() => counter.increment());
// results is [1, 2]; counter.count is 2
Der Callback ist eine Pfeilfunktion, die einen normalen Aufruf counter.increment() ausführt. Dieser Aufruf hat ein Empfängerobjekt. Der Wrapper ignoriert bewusst die von map übergebenen Werte; jeder Aufruf erhöht den Zähler einfach einmal. Diese Form ist praktisch, wenn der Callback nur an einer Stelle benötigt wird.
Eine wiederverwendbare Funktion binden
Beginne mit einem neuen Zähler bei null:
const boundInc = counter.increment.bind(counter);
const results = [1, 2].map(boundInc);
// results is [1, 2]; counter.count is 2
bind gibt eine neue Funktion zurück; es ruft die Methode noch nicht auf. Die neue Funktion behält counter als Empfängerobjekt. Eine erneute Bindung an ein anderes Objekt kann dieses Empfängerobjekt nicht ersetzen. Jeder Aufruf von bind erstellt eine eigene Funktion. Speichere daher das Ergebnis, wenn der Code später genau denselben Callback wiedererkennen muss.
Beim Binden lassen sich auch die ersten Argumente festlegen. Auf function multiply(a, b) { return a * b; } folgt const double = multiply.bind(null, 2);, sodass double(21) den Wert 42 zurückgibt. null belegt die Position des Empfängerobjekts, weil diese Funktion kein this verwendet; 2 belegt ihren ersten gewöhnlichen Parameter.
Einmal mit call oder apply ausführen
function describe(unit) {
return this.value + " " + unit;
}
describe.call({ value: 12 }, "kg"); // "12 kg"
describe.apply({ value: 12 }, ["kg"]); // "12 kg"
Beide Formen führen die Funktion sofort mit dem gewählten Empfängerobjekt aus. call übergibt Argumente einzeln; apply übergibt sie in einem Array. Der Kontext einer Pfeilfunktion wird durch ihre Umgebung festgelegt, sodass diese Methoden ihr this nicht ersetzen können.
Wird counter.increment() als Callback übergeben, führt das die Methode sofort aus und übergibt die zurückgegebene Zahl. Das ist nicht die Funktion, die map benötigt. Bei einer Ereignisregistrierung wie button.addEventListener("click", counter.increment()) ändert sich der Zähler sofort und der numerische Listener verursacht einen TypeError. Übergib einen Funktionswert, einen Pfeilfunktions-Wrapper oder eine gespeicherte gebundene Funktion.
Wichtige Erkenntnisse
- Wird eine Methode herausgelöst, verliert sie ihr ursprüngliches Empfängerobjekt.
- Ein Pfeilfunktions-Wrapper kann den benötigten Methodenaufruf später ausführen.
binderstellt eine Funktion mit einem festen Empfängerobjekt und optional festgelegten ersten Argumenten.callundapplyführen die Funktion sofort aus; sie unterscheiden sich darin, wie sie Argumente entgegennehmen.- Callback-Argumente müssen Funktionen sein, nicht das numerische Ergebnis eines Methodenaufrufs.
3Entpacke und kombiniere Daten mit Destrukturierung, Spread und Rest
Die Destrukturierung gibt ausgewählten Teilen eines Objekts oder einer geordneten Sammlung Namen. Spread erstellt Werte aus vorhandenen Teilen, während Rest die übrigen Teile sammelt. Diese Formen treten häufig gemeinsam in Funktionen auf, die Optionen entgegennehmen oder aktualisierte Datensätze zurückgeben. Wenn du genau auf ihre Position achtest, kannst du vorhersagen, welche Variablen existieren, welche Standardwerte gelten und ob verschachtelte Daten gemeinsam mit dem Original genutzt werden.
3.1 Destrukturiere Objekte
Die Objektdestrukturierung liest benannte Felder in lokale Variablen. Sie wählt Werte aus, ohne den gesamten Quelldatensatz zu kopieren.
Zuordnen und umbenennen
const book = { title: "Dune", pages: 412 };
const { pages, title: bookTitle, rating: stars = 0 } = book;
Die Zuordnung erfolgt anhand der Eigenschaftsnamen, nicht ihrer Reihenfolge. Dies deklariert pages mit dem Wert 412, bookTitle mit "Dune" und stars mit 0. Es wird keine Variable title oder rating deklariert: Der Name nach einem Doppelpunkt ist die lokale Zielvariable.
Ein fehlendes Feld liefert undefined. Ein Standardwert ersetzt nur undefined und behält null, null als Zahl, false und leere Zeichenketten bei. const { a = 5 } = { a: null }; belässt a daher bei null.
Verschachtelte Felder verfolgen
const data = {
location: { name: "Oslo" },
current: { tempC: -3, windKph: 18 }
};
const {
location: { name },
current: { tempC, windKph: wind }
} = data;
Die deklarierten Variablen sind name, tempC und wind mit den Werten "Oslo", -3 und 18. Die umgebenden Namen location und current wählen Pfade aus; sie werden nicht ebenfalls zu Variablen.
Fehlt ein äußeres Objekt, schlägt ein verschachtelter Lesezugriff fehl. const { shipping: { date } } = {}; löst einen TypeError aus. Gib einen äußeren Standardwert an, wenn dieses Feld undefined sein kann:
const { shipping: { date } = {} } = {};
// date is undefined
Dies ersetzt shipping nicht, wenn sein Wert null ist. Auch die direkte Destrukturierung von null oder undefined löst einen Fehler aus. Der Ausgangswert muss daher verwendbar sein, bevor das Entpacken beginnt.
Benannte Optionen entgegennehmen
function formatUser({ name, age = "unknown" }) {
return name + ", " + age;
}
formatUser({ name: "Mo" }) gibt "Mo, unknown" zurück. Werden die Felder wie in { age: 40, name: "Ines" } umgeordnet, ist der Rückgabewert weiterhin "Ines, 40". Ein Aufruf von formatUser ohne Argument schlägt fehl, weil kein Objekt zum Entpacken vorhanden ist. Ein Standardwert für den gesamten Parameter erlaubt diesen Aufruf:
function greet({ name = "guest" } = {}) {
return "Hi, " + name;
}
greet(); // "Hi, guest"
Der äußere Standardwert behandelt ein ausgelassenes Argument; der innere behandelt einen fehlenden Namen. Die Übergabe von null schlägt weiterhin fehl. Um vorhandenen Variablen Werte zuzuweisen, setze eine Anweisung mit Objektmuster in runde Klammern: let x, y; ({ x, y } = { x: 4, y: 7 });. Andernfalls werden die anfänglichen geschweiften Klammern als Anweisungsblock gelesen.
Wichtige Erkenntnisse
- Objektmuster ordnen Eigenschaften anhand ihres Namens zu.
- Ein Doppelpunkt benennt die Variable um; er ändert nicht den Schlüssel im Ausgangsobjekt.
- Standardwerte ersetzen
undefined, auch bei fehlenden Eigenschaften, und behaltennullbei. - Verschachtelte Muster benötigen auf jeder Ebene ein verwendbares Objekt.
- Ein Standardwert für den gesamten Parameter und ein Standardwert für eine Eigenschaft behandeln unterschiedliche fehlende Werte.
- Runde Klammern ermöglichen es einem Objektmuster, vorhandenen Variablen Werte zuzuweisen.
3.2 Destrukturiere Arrays und andere iterierbare Objekte
Die Array-Destrukturierung liest Werte anhand ihrer Position aus einem iterierbaren Objekt. Kommas steuern, welche Werte ausgewählt werden; die Variablennamen wählen keine Positionen aus.
Positionen auswählen oder überspringen
const medals = ["gold", "silver", "bronze"];
const [first, second] = medals;
const [, , third] = medals;
Die Variablen erhalten "gold", "silver" und "bronze". Leere Stellen verbrauchen Werte, ohne Variablen zu deklarieren. Ein Name, für den kein Wert mehr vorhanden ist, erhält undefined. Standardwerte ersetzen nur undefined:
const [p, q = 10] = [1]; // p is 1; q is 10
const [r = 10] = [null]; // r is null
Die übrigen Werte sammeln
const [head, ...tail] = [1, 2, 3, 4];
// head is 1; tail is [2, 3, 4]
Das abschließende Restelement erstellt ein neues Array, das leer ist, wenn nichts übrig bleibt. Es muss zuletzt stehen. Objektwerte innerhalb dieses Arrays behalten ihre Identität; beim Sammeln werden sie nicht tief geklont.
Ein zurückgegebenes Paar lesen oder Variablen vertauschen
function minMax(nums) {
return [Math.min(...nums), Math.max(...nums)];
}
const [lo, hi] = minMax([4, 9, 1]);
// lo is 1; hi is 9
Der Aufrufer hält sich an die von der zurückgebenden Funktion festgelegte Reihenfolge. Bei vielen Ergebnisfeldern ersparen benannte Objekteigenschaften das Merken von Positionen.
Mit let x = 1, y = 2; vertauscht [x, y] = [y, x]; die Variablen. Das Array auf der rechten Seite wird vor jeder der beiden Zuweisungen als [2, 1] ausgewertet. So bleiben beide alten Werte ohne temporäre Variable erhalten.
Andere iterierbare Objekte entpacken
Auch Zeichenketten und Sets lassen sich entpacken: const [initial] = "Zoe"; ergibt "Z". Sets liefern Werte in Einfügereihenfolge. Map-Einträge sind geordnete Paare:
const distances = new Map([["park", 2], ["lake", 5]]);
for (const [place, distanceKm] of distances) {
console.log(place, distanceKm);
}
Die Schleife erhält ein Paar, dann trennt das Muster dessen Schlüssel und Wert. Object.entries liefert Paare in derselben Form.
Ein einfaches Objekt ist nicht iterierbar, daher löst const [name] = { name: "Ana" }; einen TypeError aus. Verwende geschweifte Klammern, um sein benanntes Feld auszuwählen: const { name } = { name: "Ana" };. Eckige Klammern benötigen eine Folge von Werten; geschweifte Klammern wählen Eigenschaften anhand ihres Namens aus.
Wichtige Erkenntnisse
- Arraymuster ordnen anhand von Positionen zu, und leere Stellen überspringen Werte.
- Eine fehlende Position ergibt
undefined, sofern kein Standardwert es ersetzt. - Ein abschließendes Restelement sammelt die übrigen Werte in einem neuen Array.
- Arraymuster funktionieren auch mit Zeichenketten, Sets und Map-Einträgen.
3.3 Kopiere, führe zusammen und sammle mit Spread und Rest
Die drei Punkte ... haben zwei verwandte Aufgaben. Spread entfaltet vorhandene Daten in einem Wert oder Aufruf. Rest sammelt Werte in einer Variablen, wo ein Muster oder Parameter sie deklariert.
Nach Priorität zusammenführen
const defaults = { lang: "en", units: "metric", alerts: true };
const user = { lang: "pt", alerts: false };
const options = { ...defaults, ...user };
// { lang: "pt", units: "metric", alerts: false }
Objekt-Spread kopiert eigene aufzählbare Eigenschaften. Wenn ein Schlüssel erneut erscheint, setzt sich der spätere Wert durch. Stünde user vor defaults, würden die Einstellungen des Nutzers überschrieben. Werden null oder undefined mit Spread in ein Objekt übernommen, wird nichts hinzugefügt.
Spread-Kopien sind flach. Wenn sich ein verschachtelter Datensatz ändert, kopiere auch diese Ebene:
const settings = { theme: "dark", font: { size: 14, family: "serif" } };
const next = {
...settings,
font: { ...settings.font, size: 18 }
};
Der äußere Spread behält theme bei. Der innere Spread behält family bei und ersetzt size. settings.font.size bleibt 14, weil der geänderte verschachtelte Datensatz neu ist.
Einen Datensatz in einer Liste ersetzen
const todos = [{ id: 1, done: false }, { id: 2, done: false }];
const updated = todos.map(t =>
t.id === 2 ? { ...t, done: true } : t
);
map erstellt ein neues Array. Das passende Element wird zu einem neuen Objekt, daher ist updated[1].done gleich true, während todos[1].done gleich false bleibt. Das unveränderte erste Element wird wiederverwendet: updated[0] === todos[0] ist true. Für unabhängige Aktualisierungen müssen unveränderte Datensätze nicht kopiert werden.
Werte aus iterierbaren Objekten entfalten
In einem Arrayliteral oder Funktionsaufruf entnimmt Spread einem iterierbaren Objekt Werte. [...a, ...b] verbindet deren Werte zu einem neuen Array. Math.max(...[4, 9, 1]) übergibt drei Argumente und gibt 9 zurück. Ein einfaches Objekt lässt sich nicht in ein Array entfalten: [...{ a: 1 }] löst einen TypeError aus. Für Objekt-Spread und Spread iterierbarer Objekte gelten unterschiedliche Regeln dafür, was sie lesen.
Argumente oder übrige Eigenschaften sammeln
function total(...nums) {
return nums.reduce((sum, n) => sum + n, 0);
}
total(2, 3, 5); // 10
total(); // 0
Ein Restparameter erhält ein echtes Array, auch wenn er keine Werte erhält. Er muss der letzte Parameter sein und es darf nur einen geben. Das ältere arguments-Objekt ist kein echtes Array. Pfeilfunktionen haben kein eigenes arguments, können aber die Bindung einer umgebenden regulären Funktion lesen.
Objekt-Rest sammelt eigene aufzählbare Eigenschaften, die noch nicht ausgewählt wurden:
const userRecord = { id: 8, name: "Rae", password: "x9!k" };
const { password, ...publicUser } = userRecord;
// publicUser is { id: 8, name: "Rae" }
Dies erstellt einen neuen Datensatz und lässt den Ausgangsdatensatz unverändert. Die Rest-Eigenschaft muss zuletzt stehen. An der Position erkennst du die Aufgabe: Drei Punkte in einem Literal oder Aufruf entfalten Werte nach außen; drei Punkte in einer Parameterliste oder einem Destrukturierungsziel sammeln Werte nach innen.
Wichtige Erkenntnisse
- Bei überlappenden Objekt-Spreads setzen sich spätere Eigenschaften durch.
- Kopiere jede verschachtelte Ebene, die unabhängig geändert werden muss.
- Spread in Arrays und Aufrufen benötigt ein iterierbares Objekt.
- Rest sammelt übrige Argumente, Elemente oder Eigenschaften und muss zuletzt stehen.
- Eine Aktualisierung mit map kann einen geänderten Datensatz kopieren und unveränderte Datensätze wiederverwenden.
- Restparameter sind echte Arrays; das ältere
arguments-Objekt ist keines.
4Speichere Sammlungen mit Map und Set
Manche Sammlungen benötigen Schlüssel, die Objekte oder Zahlen sind, andere sollen jeden Wert nur einmal enthalten. Map und Set erfüllen diese Anforderungen direkt. Du erstellst Einträge, prüfst die Zugehörigkeit, verfolgst die Einfügereihenfolge und wandelst Sammlungen in Arrays oder Objekte um, wenn eine andere Operation diese Form benötigt. Gleichheit bleibt dabei wichtig: Zwei Datensätze mit übereinstimmenden Feldern können in beiden Sammlungen zwei getrennte Werte bleiben.
4.1 Speichere Schlüssel-Wert-Paare in einer Map
Eine Map speichert Zuordnungen zwischen Schlüsseln und Werten. Anders als die Zeichenkettenschlüssel eines einfachen Objekts kann ein Map-Schlüssel eine Zahl, ein Objekt oder ein anderer Wert sein, ohne in eine Zeichenkette umgewandelt zu werden.
Einträge erstellen und verwalten
const stock = new Map();
stock.set("apples", 12).set("pears", 7);
stock.get("apples"); // 12
stock.has("kiwis"); // false
stock.size; // 2
set fügt einen Eintrag hinzu oder ersetzt seinen Wert und gibt die Map für eine Verkettung zurück. get gibt für einen fehlenden Schlüssel undefined zurück; verwende has, um ihn von einem Eintrag mit dem Wert undefined zu unterscheiden. delete(key) gibt zurück, ob es einen Eintrag entfernt hat, und clear() leert die Sammlung.
Die Klammernotation greift auf einen anderen Speicherbereich zu: stock["plums"] = 5; fügt dem Map-Objekt eine gewöhnliche Eigenschaft hinzu. Es entsteht kein Eintrag, der für get, has oder size sichtbar ist. Verwende für Einträge die Map-Methoden.
Schlüsseltypen und Identitäten erhalten
m.set(1, "number"); m.set("1", "text"); erstellt zwei Einträge. Die Schlüssel 1 und "1" eines einfachen Objekts würden auf eine Eigenschaft verweisen. Map-Schlüssel werden wie bei === verglichen, außer dass NaN mit sich selbst übereinstimmt und Nullen mit unterschiedlichem Vorzeichen denselben Schlüssel bilden.
const person = { id: 1 };
const notes = new Map([[person, "ready"]]);
notes.get(person); // "ready"
notes.get({ id: 1 }); // undefined
Die zweite Abfrage erstellt ein neues Objekt. Übereinstimmende Felder machen es nicht zu demselben Schlüssel. Bewahre die ursprüngliche Objektreferenz auf und verwende sie erneut, wenn du ein Objekt als Schlüssel nutzt.
Paare durchlaufen und umwandeln
for (const [name, count] of stock) {
console.log(name, count);
}
Eine Map liefert [key, value]-Paare in der Reihenfolge, in der die Schlüssel erstmals eingefügt wurden. Das Ersetzen eines Werts verschiebt seinen Schlüssel nicht. keys(), values() und entries() geben iterierbare Ansichten zurück, die du durchlaufen oder mit Spread in Arrays übernehmen kannst. forEach übergibt seinem Callback zuerst den Wert und dann den Schlüssel.
new Map(Object.entries(obj)) wandelt die Einträge eines Datensatzes in eine Map um. Object.fromEntries(map) erstellt ein Objekt; verwende es bei Zeichenkettenschlüsseln, weil Objektschlüssel nicht jeden Map-Schlüsseltyp erhalten können. [...map] erstellt ein Array aus Paaren, das sich zum Speichern von Map-Einträgen als JSON eignet.
Wechselnde Schlüssel zählen
const words = "the cat saw the dog and the bird".split(" ");
const counts = new Map();
for (const word of words) {
counts.set(word, (counts.get(word) ?? 0) + 1);
}
Das erste Vorkommen beginnt bei null und addiert dann eins. Spätere Vorkommen lesen und erhöhen den gespeicherten Zähler. counts.get("the") ist 3 und counts.size ist 6: Die Größe zählt unterschiedliche Wörter, nicht alle acht Vorkommen.
Wähle ein einfaches Objekt für einen Datensatz mit bekannten Feldern, insbesondere für JSON-geeignete Daten. Wähle eine Map für wechselnde Schlüssel, häufige Größenprüfungen oder Schlüssel, deren Typ erhalten bleiben muss. Das neuere Map.groupBy erhält die Typen der Gruppenschlüssel:
const owner = { name: "Ari" };
const jobs = [{ owner, done: false }, { owner, done: true }];
const byOwner = Map.groupBy(jobs, job => job.owner);
byOwner.get(owner).length; // 2
Durchlaufe in älterem Code die Aufträge. Verwende für jeden Eigentümer has und set, um einmalig ein Gruppenarray zu erstellen, und dann get(owner).push(job), um den Datensatz hinzuzufügen. Wird der Eigentümer als Objektschlüssel verwendet, werden verschiedene Eigentümer auch dann unterschieden, wenn ihre Namensfelder übereinstimmen. Eine WeakMap kann Objekten Metadaten zuordnen, ohne anderweitig unerreichbare Schlüsselobjekte am Leben zu halten. Sie lässt sich nicht durchlaufen und hat keine Größe. Moderne WeakMaps akzeptieren auch nicht registrierte Symbole als Schlüssel.
Wichtige Erkenntnisse
- Map-Schlüssel behalten ihre Typen; Objekte werden anhand ihrer Identität verglichen.
- Verwende für Einträge
set,get,hasunddelete, nicht die Klammernotation. sizezählt Einträge und beim Durchlaufen gilt die Einfügereihenfolge der Schlüssel.- Maps werden über Schlüssel-Wert-Paare umgewandelt.
- Eine WeakMap kann Metadaten zu Objekten speichern, ohne die Schlüsselobjekte am Leben zu halten.
Map.groupByerhält die Typen der Gruppenschlüssel in einer neueren Gruppierungs-API.
4.2 Speichere eindeutige Werte in einem Set
Ein Set speichert eindeutige Werte. Seine wichtigsten Fragen sind, ob ein Wert vorhanden ist und wie sich zwei Sammlungen überschneiden.
Werte hinzufügen und prüfen
const tags = new Set(["js", "css", "js"]);
tags.size; // 2
tags.add("html");
tags.has("css"); // true
Das Hinzufügen eines vorhandenen Werts ändert nichts. add gibt das Set für eine Verkettung zurück. delete(value) gibt zurück, ob der Wert entfernt wurde, während clear() alle Werte entfernt. Der Konstruktor nimmt ein iterierbares Objekt entgegen: Verwende new Set([1, 2, 3]). new Set(1, 2, 3) löst einen TypeError aus, weil seine erste Eingabe nicht iterierbar ist. Eine Zeichenkette ist iterierbar, daher enthält new Set("hello") die Werte "h", "e", "l" und "o".
Ein Set hat keine Positionen mit Indizes. tags[0] ist undefined. Durchlaufe es mit for...of, rufe forEach auf oder wandle es für Operationen wie map und filter in ein Array um. Beim Durchlaufen gilt die Einfügereihenfolge; wird ein Wert entfernt und erneut hinzugefügt, steht er am Ende.
Duplikate ohne Sortieren entfernen
const unique = [...new Set([3, 1, 3, 2, 1])];
// [3, 1, 2]
Das Set behält das erste Vorkommen jedes Werts. Spread überträgt diese Werte in ein Array. Array.from(set) führt dieselbe Umwandlung durch.
Werte werden wie bei === verglichen, außer dass NaN mit sich selbst übereinstimmt; Nullen mit unterschiedlichem Vorzeichen zählen als ein Wert. Objektwerte werden anhand ihrer Identität verglichen: new Set([{ id: 1 }, { id: 1 }]).size ist 2. Um einen Datensatz pro ID zu behalten, erstelle eine Map mit dieser ID als Schlüssel und lies dann ihre Werte. Spätere Datensätze mit derselben ID ersetzen frühere, weil set einen vorhandenen Eintrag aktualisiert.
Bei wiederholten Zugehörigkeitsprüfungen in großen Sammlungen vermeidet ein Set die Einzelprüfung durch includes eines Arrays. Verwende es, wenn die Anwesenheit wichtiger ist als die Position.
Zwei Sammlungen vergleichen
Neuere Set-Methoden sind seit 2024 in den großen Browsern verfügbar. Dabei enthalte a die Werte 1, 2, 3, 4 und b die Werte 3, 4, 5:
| Operation | Bedeutung | Ergebniswerte |
|---|---|---|
a.union(b) | In mindestens einer Sammlung | 1, 2, 3, 4, 5 |
a.intersection(b) | In beiden | 3, 4 |
a.difference(b) | In a, aber nicht in b | 1, 2 |
a.symmetricDifference(b) | In genau einer | 1, 2, 5 |
Diese Operationen geben neue Sets zurück. isSubsetOf prüft, ob jeder Wert in der anderen Sammlung enthalten ist. isSupersetOf prüft die umgekehrte Beziehung. isDisjointFrom prüft, ob die Sammlungen keine gemeinsamen Werte haben. Alle drei geben boolesche Werte zurück. Zum Beispiel ist new Set([3, 4]).isSubsetOf(a) gleich true. Die Differenz hat eine Richtung: Werte in b, aber nicht in a ergäben nur 5.
In einer älteren Umgebung lässt sich eine Schnittmenge als new Set([...a].filter(x => b.has(x))) schreiben.
Das gewöhnliche JSON.stringify(set) erzeugt "{}", wobei die gespeicherten Werte verloren gehen. Wandle das Set vor dem Schreiben von JSON in ein Array um und verwende beim Lesen new Set(parsedArray). Ein WeakSet kann Objekte als verarbeitet markieren, ohne anderweitig unerreichbare Objekte am Leben zu halten. Es lässt sich nicht durchlaufen. Moderne WeakSets akzeptieren auch nicht registrierte Symbole.
Wichtige Erkenntnisse
- Ein Set speichert jeden unterschiedlichen Wert einmal und prüft mit
has, ob er vorhanden ist. - Wandle ein Set für den Zugriff über Indizes oder für Arraymethoden in ein Array um.
- Objektwerte bleiben getrennt, sofern ihre Referenzen nicht übereinstimmen.
- Vereinigungsmenge, Schnittmenge, Differenzmenge und symmetrische Differenz beantworten unterschiedliche Fragen zur Zugehörigkeit.
- Die Differenz hängt davon ab, welches Set zuerst steht.
- Wandle Set-Werte vor dem Schreiben von JSON in ein Array um.
- Ein WeakSet kann Objekte markieren, ohne sie am Leben zu halten.
5Wandle Daten in JSON und JSON in Daten um
JSON überträgt strukturierte Daten als Text. Die Umwandlung zwischen diesem Text und JavaScript-Werten zur Laufzeit ist nur dann nützlich, wenn du weißt, welche Informationen dabei erhalten bleiben. Du lernst, gültiges JSON zu erkennen, das Schreiben von Werten zu steuern und fehlerhafte Eingaben beim Lesen zu behandeln. Auch nach erfolgreichem Parsen muss die Struktur geprüft werden, bevor das Programm auf die Felder vertraut; gültiger Text allein kann die erwarteten Daten nicht garantieren.
5.1 Lies und schreibe Daten im JSON-Format
JSON, kurz für JavaScript Object Notation, ist ein sprachunabhängiges Textformat für strukturierte Daten. Ein Objekt ist ein JavaScript-Wert zur Laufzeit; JSON ist Text, der einen solchen Wert beschreiben kann.
Die sechs Wertarten erkennen
JSON unterstützt Objekte, Arrays, Zeichenketten, Zahlen, boolesche Werte und null. Jeder dieser Werte kann auf oberster Ebene stehen. Der Text 42 ist auch ohne geschweifte Klammern gültiges JSON. JSON hat keine Darstellung für Funktionen, undefined, Datumswerte als eigenen Typ, Map, Set, NaN oder Infinity.
{
"name": "Amara",
"age": 34,
"languages": ["en", "yo"],
"address": null,
"member": true
}
Dieselben Grundideen zur Struktur finden sich in JavaScript-Literalen, aber die erlaubte Schreibweise ist strenger. JSON wird in Konfigurationen und beim Datenaustausch verwendet. Ausgetauschtes JSON verwendet die UTF-8-Kodierung und den Medientyp application/json; JSON-Dateien verwenden die Endung .json.
Die Syntaxregeln anwenden
Jeder Objektschlüssel muss eine Zeichenkette in doppelten Anführungszeichen sein. Auch Zeichenketten benötigen doppelte Anführungszeichen. Kommas trennen Eigenschaften oder Arrayelemente, aber nach dem letzten Element darf kein Komma stehen. Kommentare sind verboten. Leerraum zwischen Werten und Satzzeichen ist erlaubt.
| Text | Warum er fehlschlägt |
|---|---|
{name: "Amara"} | Dem Schlüssel fehlen doppelte Anführungszeichen. |
{'name': 'Amara'} | Einfache Anführungszeichen begrenzen keine JSON-Zeichenketten. |
{"a": 1,} | Auf das letzte Komma folgt keine Eigenschaft. |
{"a": undefined} | Undefined ist kein JSON-Wert. |
Zahlen verwenden die Dezimalschreibweise. 1.5e3, -0.25 und 0 sind gültig. 07, +1 und 0x1F sind ungültig, weil JSON führende Nullen, ein führendes Pluszeichen und die Hexadezimalschreibweise verbietet.
Zeichen innerhalb von Zeichenketten maskieren
Verwende innerhalb einer JSON-Zeichenkette \" für ein doppeltes Anführungszeichen, \\ für einen umgekehrten Schrägstrich, \n für einen Zeilenumbruch und \t für einen Tabulator. Ein tatsächlicher Zeilenumbruch darf innerhalb einer JSON-Zeichenkette nicht vorkommen. Lass JSON.stringify Escape-Sequenzen aus tatsächlichen Zeichenkettenwerten erzeugen, damit eingebettete Anführungszeichen die Ausgabe nicht beschädigen können.
Eine Unicode-Escape-Sequenz besteht aus einem umgekehrten Schrägstrich, dem Buchstaben u und vier Hexadezimalziffern für eine UTF-16-Codeeinheit. Zum Beispiel stellt \u00e9 das Zeichen é dar. Ein Zeichen außerhalb dieses Bereichs kann zwei solche Escape-Sequenzen benötigen; es kann auch direkt in die Zeichenkette geschrieben werden. Die Anführungszeichen um JSON-Text im JavaScript-Quellcode bilden eine eigene Ebene gegenüber den Anführungszeichen innerhalb des JSON-Texts selbst.
Bezeichner erhalten und doppelte Schlüssel vermeiden
JavaScript-Zahlen erhalten jede ganze Zahl im sicheren Bereich von -9007199254740991 bis einschließlich 9007199254740991 exakt. Außerhalb dieses Bereichs bleiben manche ganzen Zahlen exakt und andere werden gerundet. Das Parsen von '{"id":9007199254740993}' ergibt für id den Wert 9007199254740992. Speichere lange Bezeichner als JSON-Zeichenketten, wenn ihre exakten Ziffern wichtig sind.
Objektschlüssel sollten innerhalb jedes JSON-Objekts eindeutig sein. Das JavaScript-Verfahren JSON.parse behält das letzte Vorkommen, wenn ein Schlüssel wiederholt wird: Das Parsen von '{"a":1,"a":2}' erzeugt { a: 2 }. Aus diesem wiederholten Namen lassen sich getrennte Eigenschaften nicht wiederherstellen.
Wichtige Erkenntnisse
- JSON ist Text mit sechs Wertarten, darunter primitive Werte auf oberster Ebene.
- Schlüssel und Zeichenketten benötigen doppelte Anführungszeichen; Kommentare und abschließende Kommas sind ungültig.
- JSON-Zahlen schließen Hexadezimalschreibweise, führende Pluszeichen und führende Nullen aus.
- Escape-Sequenzen stellen Sonderzeichen innerhalb von Zeichenketten dar.
- Verwende Zeichenketten für lange Bezeichner, deren exakte Ziffern erhalten bleiben müssen.
- Wiederholte Objektschlüssel sind unsicher;
JSON.parsebehält den letzten Wert.
5.2 Wandle Werte mit JSON.stringify in JSON-Text um
JSON.stringify wandelt unterstützte JavaScript-Werte in JSON-Text um. Entscheide vor dem Umwandeln eines Datensatzes mit Methoden oder Sammlungswerten, was der Text erhalten muss.
Kompakten oder eingerückten Text schreiben
const person = { name: "Amara", age: 34, tags: ["admin"] };
const text = JSON.stringify(person);
// '{"name":"Amara","age":34,"tags":["admin"]}'
Das Ergebnis ist eine Zeichenkette, daher ist typeof text gleich "string". Eigene aufzählbare Eigenschaften mit Zeichenkettenschlüsseln werden in der Reihenfolge von Object.keys geschrieben. JSON.stringify(person, null, 2) fügt Zeilenumbrüche und zwei Leerzeichen Einrückung pro Ebene hinzu. Das zweite Argument ist null, weil kein replacer-Parameter verwendet wird. Die numerische Einrückung ist auf 10 Leerzeichen begrenzt; von einer zur Einrückung verwendeten Zeichenkette werden höchstens die ersten 10 Zeichen verwendet.
Weggelassene und geänderte Werte vorhersagen
const data = {
a: undefined,
b: () => 1,
c: NaN,
d: [undefined, Infinity]
};
JSON.stringify(data); // '{"c":null,"d":[null,null]}'
Eine Objekteigenschaft mit undefined, einer Funktion oder einem Symbol wird weggelassen. In einem Array wird ein solcher Wert zu null, sodass die Position erhalten bleibt. NaN und Infinity werden an beiden Stellen zu null. Auf oberster Ebene führen nicht unterstützte Werte wie undefined oder eine Funktion dazu, dass stringify den Wert undefined statt JSON-Text zurückgibt.
Ein Date schreibt seine ISO-Zeichenkette in UTC über toJSON. Gewöhnliche Map- und Set-Einträge werden nicht geschrieben, sodass beide Sammlungsarten zu {} werden. Wandle Set-Werte in ein Array und Map-Einträge in Paare oder ein Objekt mit Zeichenkettenschlüsseln um, bevor du sie schreibst.
Eine zirkuläre Referenz und ein gewöhnlicher BigInt wie 10n verursachen einen TypeError. Gemeinsam genutzte Referenzen, die keinen Zyklus bilden, lassen sich serialisieren, aber JSON erhält ihre gemeinsame Identität nicht.
Daten mit einem replacer-Parameter auswählen
const user = { name: "Rae", email: "rae@example.com", password: "x9!k", age: 31 };
JSON.stringify(user, ["name", "email"]);
// '{"name":"Rae","email":"rae@example.com"}'
Ein replacer-Array wählt Eigenschaftsnamen aus. Eine replacer-Funktion transformiert Werte bei ihrer Verarbeitung, beginnend mit der gesamten Eingabe unter dem Schlüssel "":
JSON.stringify(user, (key, value) =>
key === "password" ? undefined : value
);
Die Rückgabe von undefined lässt eine Objekteigenschaft weg, macht eine Arrayposition zu null oder führt bei der Rückgabe für den Wurzelwert zu einem Gesamtergebnis von undefined. Gib für Daten, die du behalten möchtest, den unveränderten Wert zurück.
Die toJSON()-Methode eines Objekts kann dessen Darstellung wählen. Für { celsius: 21, toJSON() { return { c: this.celsius }; } } schreibt die Serialisierung '{"c":21}'.
Erstelle JSON nicht selbst durch das Verbinden von Zeichenketten in Anführungszeichen: Eingebettete Anführungszeichen oder Zeilenumbrüche können seine Syntax beschädigen. Wandle auch bereits serialisierten Text nicht in der Erwartung erneut in eine JSON-Zeichenkette um, eine Objektdarstellung zu erhalten. Die Serialisierung von '{"a":1}' kodiert eine Zeichenkette; einmaliges Parsen dieses Ergebnisses gibt eine Zeichenkette zurück, kein Objekt.
Wichtige Erkenntnisse
JSON.stringifygibt normalerweise JSON-Text zurück; nicht unterstützte Werte auf oberster Ebene könnenundefinedergeben.- Nicht unterstützte Objekteigenschaften verschwinden, während nicht unterstützte Arrayelemente zu
nullwerden. - Datumswerte werden zu Zeichenketten; Map und Set benötigen eine ausdrückliche Umwandlung.
- Zirkuläre Strukturen und gewöhnliche BigInts lösen einen
TypeErroraus. - replacer-Parameter und
toJSONsteuern die geschriebene Darstellung. - Die erneute Serialisierung von JSON-Text kodiert eine Zeichenkette, nicht das darin enthaltene Objekt.
5.3 Wandle JSON-Text mit JSON.parse in Werte um
JSON.parse liest JSON-Text und gibt den Wert zurück, den er beschreibt. Das Parsen prüft die Syntax des Textes; ob das Ergebnis zu deinem Programm passt, musst du gesondert prüfen.
Den Wert lesen und dann seine Felder prüfen
const data = JSON.parse('{"city":"Lima","tempC":19.5}');
data.tempC + 1; // 20.5
Die äußeren einfachen Anführungszeichen begrenzen eine JavaScript-Zeichenkette. Die doppelten Anführungszeichen darin gehören zu JSON. Das Parsen erstellt ein einfaches Objekt mit einer numerischen tempC-Eigenschaft. Ein Text, der ein Array beschreibt, erzeugt ein Array; primitive JSON-Texte erzeugen ihre entsprechenden primitiven Werte.
Daten, die bereits ein Objekt sind, müssen nicht geparst werden. JSON.parse({ a: 1 }) wandelt dieses Argument zuerst in "[object Object]" um und löst dann einen SyntaxError aus. Auch JSON.parse(undefined) schlägt fehl, weil "undefined" kein gültiger JSON-Text ist.
Ungültigen Text behandeln
function safeParse(text, fallback) {
try {
return JSON.parse(text);
} catch (error) {
return fallback;
}
}
safeParse("{ok:true}", null); // null
Fehlerhafte Eingaben, darunter eine leere Zeichenkette, JSON-Zeichenketten in einfachen Anführungszeichen, Schlüssel ohne Anführungszeichen und abschließende Kommas, lösen einen SyntaxError aus. Wird dieser Fehler abgefangen, erhält das Programm eine gezielte Rückfalllösung, statt angehalten zu werden. Auch ein erfolgreich geparstes null ist möglich. Entscheide daher, wie der Aufrufer eine Rückfalllösung von gültigen Daten unterscheiden soll, wenn dieser Unterschied wichtig ist.
Ausgewählte Werte mit einer Reviver-Funktion wiederherstellen
Ein als Text gespeichertes Datum kommt als Zeichenkette zurück. Ein Array aus Schlüssel-Wert-Paaren bleibt ein Array, bis new Map(pairs) es in eine Map umwandelt. Beim Schreiben weggelassene Funktionen lassen sich aus dem verbleibenden Text nicht wiederherstellen.
const text = '{"title":"Dentist","due":"2026-03-01T09:00:00.000Z"}';
const event = JSON.parse(text, (key, value) =>
key === "due" ? new Date(value) : value
);
Die Reviver-Funktion besucht innere Werte vor den Werten, die sie enthalten, und endet mit dem gesamten Ergebnis unter dem Schlüssel "". Die Rückgabe eines Werts ersetzt den aktuellen Wert. Die Rückgabe von undefined entfernt diese Eigenschaft; wird es für den Wurzelwert zurückgegeben, wird das gesamte Parsergebnis zu undefined. Wird return value für andere Schlüssel vergessen, können daher Daten gelöscht werden, die du behalten wolltest.
Struktur prüfen und einen Roundtrip planen
Gültiges JSON kann dennoch die falschen Typen enthalten. Das Parsen von '{"temp":"19"}' lässt eine Zeichenkette zurück, sodass data.temp + 1 durch Verkettung "191" ergeben würde. Prüfe vor dem Rechnen Pflichtfelder und Typen, etwa mit typeof data?.temp === "number". Wandle nur dann mit Number um, wenn das vorgesehene Format eine numerische Zeichenkette erlaubt; optionale Verkettung und ?? können Felder behandeln, die fehlen dürfen.
Für const settings = { theme: "dark", volume: 0.8, recent: ["a.txt"] }; erzeugt die Serialisierung 48 Zeichen JSON-Text. Das Parsen stellt dieselben Felddaten wieder her, aber loaded === settings ist false, weil das Parsen neue Objekte erstellt. Ein Date kommt als Zeichenkette zurück, eine Objekteigenschaft mit dem Wert undefined verschwindet und ein nicht umgewandeltes Set kommt als {} zurück. Wandle besondere Werte vor dem Schreiben um und stelle ihre vorgesehenen Typen nach dem Lesen wieder her.
Wichtige Erkenntnisse
JSON.parseliest Text und löst bei fehlerhaftem JSON einenSyntaxErroraus.- Erfolgreiches Parsen prüft weder die erforderlichen Felder noch ihre Typen.
- Eine Reviver-Funktion besucht Kindwerte zuerst und muss Werte zurückgeben, die du behalten möchtest.
- JSON-Roundtrips erstellen neue Objekte und erhalten nur darstellbare Daten.
- Stelle Sammlungs- und Datumstypen nach dem Parsen ausdrücklich wieder her.
Objekte und JSON in JavaScript: Beispiele
1Verfolge einen Sendungsdatensatz
16 Schritte
- 1EinführungErstelle einen Datensatz, den du untersuchen kannst
Eine Sendung umfasst eine ID, ein Ziel und Paketdatensätze. Du erstellst sie, untersuchst ihre Felder und verfolgst gemeinsam genutzte und kopierte Daten. Zwei Namen können dieselbe Referenz auf einen Datensatz enthalten, und eine flache Kopie nutzt verschachtelte Ebenen weiterhin gemeinsam. Eine Aktualisierung kann daher Daten erreichen, die du getrennt halten wolltest.
Die Sendungsbeispiele werden über die Folien hinweg fortgeführt, sofern ein Schritt nicht ausdrücklich ein separates Objekt erstellt.
- 2BeispielErstelle die Sendung
const shipment = { id: "s12", destination: "Porto", delayMin: 0 };Das Literal erstellt drei Eigenschaften. Die Verspätung wird in Minuten gemessen; auch null ist ein gültiger Wert.
shipment.destinationliest"Porto". Const erlaubt die Aktualisierung von Eigenschaften. - 3BeispielWähle ein Feld zur Laufzeit des Programms
const field = "destination"; shipment[field] = "Braga"; shipment.checked = true;Der Zugriff mit eckigen Klammern wertet field aus und aktualisiert die Eigenschaft destination. Die Zuweisung fügt außerdem checked hinzu, weil die Eigenschaft zuvor nicht existierte. Die Sendung hat weiterhin dieselbe Identität; keine der beiden Operationen ersetzt das äußere Objekt.
shipment.fieldwürde stattdessen eine separate Eigenschaft mit dem wörtlichen Namen"field"erstellen. - 4HerausforderungLies einen berechneten Namen
Was liest
shipment[field]jetzt und besitzt die Sendung eine eigene Eigenschaft field?---reveal---
Der Ausdruck liest
"Braga". Die Variable field enthält den Schlüssel"destination", sodass sowohl die Aktualisierung als auch der Lesezugriff diese Eigenschaft erreichen.Object.hasOwn(shipment, "field")ist false, weil keine Eigenschaft mit dem wörtlichen Namen field erstellt wurde. Eine Variable, mit der eine Eigenschaft ausgewählt wird, wird nicht selbst Teil des Datensatzes. - 5ErklärungPrüfe null, ohne den Wert zu verlieren
shipment.delayMinist null, sodass eine Bedingung, die den Wahrheitswert prüft, ihren Anweisungsblock überspringt. Die Eigenschaft existiert trotzdem.Object.hasOwn(shipment, "delayMin")gibt true zurück. Verwende für gespeicherte Felder eine Prüfung auf eigene Eigenschaften; der Operator in berücksichtigt auch geerbte Eigenschaften. - 6BeispielLies die Einträge
const pairs = Object.entries(shipment); const count = Object.keys(shipment).length;Es gibt nun vier eigene aufzählbare Felder mit Zeichenkettenschlüsseln, darunter checked. Entries liefert für jedes ein
[key, value]-Paar. Du kannst sie mitfor (const [key, value] of pairs)durchlaufen, um beide Teile zu untersuchen. Eine direkte for...of-Schleife über das einfache shipment-Objekt würde einen Fehler auslösen, weil dieses Objekt nicht iterierbar ist. - 7HerausforderungUnterscheide Existenz und Wert
Angenommen,
shipment.note = undefined;wird hinzugefügt. Was gebenshipment.noteundObject.hasOwn(shipment, "note")zurück?---reveal---
Sie geben undefined und true zurück. Die Zuweisung erstellt die Eigenschaft, obwohl ihr Wert undefined ist. Würde die Eigenschaft gelöscht, änderte sich das Ergebnis der Existenzprüfung zu false, während ein späterer Lesezugriff weiterhin undefined liefern würde. Der Wert allein kann diese beiden Situationen nicht unterscheiden.
- 8AnalogieVerfolge zwei Wege zu einem Datensatz
Eine Referenz funktioniert wie ein Weg zu einem Datensatz: Wird der Weg kopiert, entsteht eine weitere Möglichkeit, dasselbe Ziel zu erreichen. Es wird kein zweiter Datensatz erstellt.
const alias = shipment; alias.checked = false;shipment.checkedist nun ebenfalls false. Beide Variablennamen führen zu einem Objekt, daher istalias === shipmentgleich true. Übereinstimmende Referenzen erklären die gemeinsame Aktualisierung; zwischen zwei Kopien wurde kein Synchronisierungsschritt ausgeführt. - 9BeispielFüge Daten hinzu, die eine flache Kopie gemeinsam nutzt
shipment.packages = [{ massG: 450 }, { massG: 700 }]; const shallow = { ...shipment }; shallow.destination = "Faro"; shallow.packages[0].massG = 500;Der neue äußere Datensatz hat ein eigenes Ziel, daher bleibt
shipment.destinationgleich Braga. Sein packages-Wert ist dieselbe Arrayreferenz wie zuvor. Über diesen gemeinsam genutzten Pfad wird auch die Masse des ersten Pakets in der ursprünglichen Sendung auf 500 geändert. - 10BeispielErstelle eine unterstützte tiefe Kopie
const deep = structuredClone(shipment); deep.packages[0].massG = 600;Das erste ursprüngliche Paket bleibt bei 500 g, weil die tiefe Kopie ein eigenes verschachteltes Array und eigene Paketobjekte hat. Dieser Datensatz enthält nur unterstützte Daten. Enthielte er eine Eigenschaft, deren Wert eine Funktion ist, würde structuredClone einen DataCloneError auslösen, statt diese Methode unbemerkt wegzulassen.
- 11HerausforderungBestimme die Wirkung des Einfrierens
Führe diese Anweisungen aus. Löst die verschachtelte Zuweisung einen Fehler aus und wie groß ist danach die zweite Masse?
Object.freeze(shipment); shipment.packages[1].massG = 750;---reveal---
Sie gelingt und setzt die Masse auf 750. Das Einfrieren von shipment schützt dessen eigene Eigenschaften, aber nicht das referenzierte Array oder dessen Datensätze. Eine Neuzuweisung von
shipment.destinationwürde im strikten Modus einen TypeError auslösen; diese verschachtelte Zuweisung erreicht ein anderes, nicht eingefrorenes Objekt. - 12BeispielBerechne die aktuelle Gesamtmasse
const totalG = shipment.packages.reduce( (sum, pack) => sum + pack.massG, 0 );Nach den vorherigen Aktualisierungen enthält die ursprüngliche Sendung die Massen 500 und 750 g. Reduce beginnt bei null, addiert 500 und dann 750 und ergibt 1250. Die Gesamtmasse wird aus den aktuellen Paketen berechnet. Wenn sich deren Massen später ändern, führe die Berechnung erneut aus; diese gespeicherte Zahl berechnet sich nicht selbst neu.
- 13TippSichere einen optionalen Pfad ab
const contactName = shipment.contact?.name ?? "Unassigned";Im Datensatz gibt es keine Eigenschaft contact, daher ergibt die optionale Verkettung undefined und die Rückfalllösung liefert
"Unassigned". Dieser Pfad darf fehlen. Halte Pflichtfelder für die Validierung sichtbar, statt alle Fehler unbemerkt durch Standardwerte zu ersetzen. Die Rückfalllösung für null und undefined behält außerdem einen absichtlich leeren Namen bei, anders als eine Rückfalllösung mit logischem ODER. - 14HerausforderungBehalte eine gültige null bei
Was geben
shipment.delayMin ?? 10undshipment.delayMin || 10zurück?---reveal---
Der erste Ausdruck gibt 0 zurück; der zweite gibt 10 zurück. Der Nullish-Coalescing-Operator ersetzt nur null oder undefined, während das logische ODER jeden Falsy-Wert ersetzt. Für diese Sendung ist eine Verspätung von null Minuten erfasst. Würde sie als fehlend behandelt, entstünde eine Verspätung, die in den gespeicherten Daten nie angegeben wurde.
- 15HerausforderungKombiniere eine Kopie mit einer optionalen Aktualisierung
Mit
const next = { ...shipment };wird ein neuer Datensatz erstellt, danach folgtnext.packages[0].massG = 520;. Was geschieht mit der ersten Masse von shipment und ist next dasselbe äußere Objekt?---reveal---
Die ursprüngliche Masse wird zu 520, weil das verschachtelte Array gemeinsam genutzt wird.
next === shipmentist false, weil Spread ein neues äußeres Objekt erstellt hat. Das Kopieren des äußeren Datensatzes trennt Zuweisungen an seine eigenen Eigenschaften, macht aber nicht einen gesamten verschachtelten Pfad unabhängig. - 16ZusammenfassungWähle die passende Prüfung für die Aufgabe
Wähle eine Eigenschaft anhand eines wörtlichen oder berechneten Schlüssels und unterscheide Existenz vom Wahrheitswert. Verfolge vor einer Aktualisierung, ob ihr Pfad gemeinsam genutzte Daten erreicht.
Kopiere verschachtelte Ebenen, die unabhängig sein müssen. Berechne abgeleitete Summen erneut, nachdem sich ihre Eingabewerte geändert haben.
2Halte eine Aktion mit ihrem Objekt verbunden
12 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungVerfolge die Weitergabe einer Aktion
- 2BeispielErstelle und rufe eine Aktion auf
- 3HerausforderungLies die Aktion, ohne sie auszuführen
- 4BeispielEntleihe die reguläre Funktion
- 5HerausforderungLöse die entliehene Methode ab
- 6KernaussageSetze eine Pfeilfunktion in die Methode
- 7BeispielUmschließe den benötigten Aufruf
- 8BeispielBinde einen Callback einmalig
- 9HerausforderungWähle zwischen sofortiger und späterer Ausführung
- 10TippGib einer bestehenden Bindung Vorrang
- 11HerausforderungVerfolge eine gebundene Methode über ein anderes Objekt
- 12ZusammenfassungLies die Aufrufform
3Entpacke Optionen und erstelle einen aktualisierten Datensatz
14 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungLies kompakte Syntax in kleinen Schritten
- 2BeispielWähle Felder aus und benenne sie um
- 3BeispielGehe in ein verschachteltes Muster
- 4HerausforderungLies ein umbenanntes verschachteltes Feld
- 5HerausforderungUnterscheide null von einem fehlenden Wert
- 6BeispielEntpacke einen zurückgegebenen Wertebereich
- 7BeispielSammle den Rest in einem eigenen Array
- 8HerausforderungVertausche Werte, bevor du sie verwendest
- 9BeispielFühre Standardwerte mit überschreibenden Werten zusammen
- 10BeispielKopiere die verschachtelte Ebene, die sich ändert
- 11VerbindungEntferne ein Feld aus dem neuen Datensatz
- 12HerausforderungWähle eine unabhängige Aktualisierung
- 13HerausforderungVerbinde Eintragsmuster mit Spread
- 14ZusammenfassungErkenne die Aufgabe, bevor du Werte verfolgst
4Verfolge Zählwerte und eindeutige Zugehörigkeit
11 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungWähle, was sich die Sammlung merken muss
- 2BeispielErstelle Zählwerte mit Map-Methoden
- 3TippHalte Einträge und Eigenschaften getrennt
- 4HerausforderungHalte Schlüsseltypen auseinander
- 5BeispielVerwende einen Objektschlüssel erneut
- 6BeispielSammle eindeutige Bezeichnungen
- 7HerausforderungEntscheide, ob Datensätze Duplikate sind
- 8BeispielFinde die gemeinsamen und fehlenden Bezeichnungen
- 9KernaussageÄndere die Frage nach der Zugehörigkeit
- 10HerausforderungVerbinde Zählwerte mit der Zugehörigkeit
- 11ZusammenfassungStimme die Struktur auf die Operation ab
5Schreibe, lies und prüfe JSON-Daten
14 Schritte
Speichere diese Einheit, um jede Interaktive Lektion Schritt für Schritt durchzugehen.
- 1EinführungPlane beide Richtungen der Umwandlung
- 2ErklärungLies Text als Text
- 3HerausforderungBehebe ein Syntaxproblem
- 4BeispielUntersuche die aktuellen Einstellungen
- 5BeispielWandle die Sammlung vor dem Schreiben um
- 6TippLass den Serialisierer Zeichenketten maskieren
- 7HerausforderungBestimme das Ergebnis für ein nicht unterstütztes Arrayelement
- 8BeispielParse und stelle die Zugehörigkeitsprüfung wieder her
- 9BeispielBehandle fehlerhaften Text gezielt
- 10HerausforderungPrüfe einen gültigen, aber ungeeigneten Wert
- 11ErklärungStelle ein Feld mit einer Reviver-Funktion wieder her
- 12HerausforderungErhalte die Unterscheidung von Map-Schlüsseln
- 13VerbindungHalte Klonen und Austausch auseinander
- 14ZusammenfassungPrüfe Syntax, Struktur und Darstellung
Objekte und JSON in JavaScript: Übungsaufgaben
Set 1: Lies Datensätze und verfolge Werte10 Übungsfragen
Frage 1 von 10
Was gibt sensor[field] zurück?
const sensor = { tempC: 16, field: "room" };
const field = "tempC";
Antwort zeigenAntwort ausblenden
"tempC", um die Eigenschaft mit dem Wert 16 auszuwählen. Der Zugriff mit Punkt in sensor.field würde stattdessen die wörtliche Eigenschaft field lesen und "room" zurückgeben.Frage 2 von 10
Was gibt Object.hasOwn(record, "enabled") zurück?
const record = { enabled: false };
Antwort zeigenAntwort ausblenden
Frage 3 von 10
Welche Werte haben record.region und record.key?
const key = "region";
const record = { [key]: "east" };
record[key] = "west";
Antwort zeigenAntwort ausblenden
"west". Eine Eigenschaft mit dem wörtlichen Namen key wird nicht erstellt, daher gibt das Lesen von record.key undefined zurück.Frage 4 von 10
Welchen Wert hat meter.value nach diesem Aufruf?
const meter = {
value: 7,
add() { this.value += 3; }
};
meter.add();
Antwort zeigenAntwort ausblenden
Frage 5 von 10
Was gibt right.read() zurück?
const left = { name: "Ivo", read() { return this.name; } };
const right = { name: "Nia", read: left.read };
Antwort zeigenAntwort ausblenden
right aufgerufen, daher ist this gleich right und der zurückgegebene Name ist "Nia". Die Funktion wurde ursprünglich in left geschrieben, doch diese Stelle bindet ihr Empfängerobjekt nicht. Die Rückgabe von "Ivo" würde den ursprünglichen Speicherort mit dem beim aktuellen Aufruf verwendeten Objekt verwechseln.Frage 6 von 10
Welche Werte haben title und score nach der Destrukturierung?
const { name: title, score = 8 } = { name: "Reef", score: null };
Antwort zeigenAntwort ausblenden
name in die lokale Variable title. Sein Standardwert für score wird nur bei undefined verwendet, daher bleibt das ausdrücklich angegebene null erhalten. Würde null durch 8 ersetzt, würde die weiter gefasste Regel für Standardwerte bei null und undefined auf die Destrukturierung angewendet, die nur bei undefined greift.Frage 7 von 10
Welchen Wert erhält third?
const [, , third] = [4, 9, 12, 18];
Antwort zeigenAntwort ausblenden
Frage 8 von 10
Welche Werte haben m.size und m.get(2)?
const m = new Map([[2, "number"], ["2", "text"]]);
Antwort zeigenAntwort ausblenden
"2" zwei getrennte Einträge belegen. Die Abfrage mit der numerischen 2 gibt "number" zurück. Eine Größe von 1 ergäbe sich, wenn beide Schlüssel als dieselbe Zeichenkette behandelt würden, wie es bei diesen Namen als gewöhnlichen Objekteigenschaften der Fall ist.Frage 9 von 10
Antwort zeigenAntwort ausblenden
Frage 10 von 10
Welcher Text wird zurückgegeben?
JSON.stringify({
note: undefined,
values: [undefined, NaN],
ok: false
});
Antwort zeigenAntwort ausblenden
note als null erhalten bleiben, wäre die Arrayregel fälschlich auf eine Objekteigenschaft angewendet worden; das Löschen von Arraypositionen würde deren Struktur ändern.Set 2: Wende Muster an und erhalte Empfängerobjekte10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
Was gibt trip.host?.name ?? "Guest" zurück?
const trip = { host: null };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
Was sind die endgültigen Werte von a.level und a === b?
const a = { level: 2 };
const b = a;
b.level = 5;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
Welche Werte haben source.mode und source.layout.width danach?
const source = { mode: "day", layout: { width: 40 } };
const copy = { ...source };
copy.mode = "night";
copy.layout.width = 60;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
Welche Funktion kann an map übergeben werden, sodass jeder Aufruf tally aktualisiert?
const tally = { n: 0, tick() { return ++this.n; } };
const result = ["x", "y"].map(/* callback */);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
Dieser Code läuft auf der obersten Modulebene. Was geschieht beim Aufruf von card.read()?
const card = { title: "Basin", read: () => this.title };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
Welche Werte haben next.mode und base.panel.width nach next.panel.width = 90?
const base = { mode: "wide", panel: { width: 50 } };
const next = { mode: "small", ...base, panel: { ...base.panel } };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
Welchen Wert erhält size?
const { size = 6 } = {};
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
Welches Array erzeugt dieser Ausdruck?
[...new Set(["red", "blue", "red", "green", "blue"])];
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
Was ist der endgültige Wert von loaded?
const loaded = JSON.parse('{"count":4,"tag":"a"}', (key, value) => {
if (key === "count") return value * 2;
});
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
Was geschieht, wenn dieser Text geparst wird?
JSON.parse('{"mode":"fast","mode":"slow"}');
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 3: Transformiere Sammlungen und stelle Daten wieder her10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
Welches Objekt erstellt der Ausdruck?
Object.fromEntries(
Object.entries({ north: 3, south: 5 })
.map(([key, value]) => [key, value + 2])
);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
Was gibt options.limit ?? 12 zurück?
const options = { limit: 0 };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
Was muss add zurückgeben, damit basket.add("pear").add("fig") zweimal denselben Warenkorb verwendet?
const basket = {
items: [],
add(item) { this.items.push(item); /* return here */ }
};
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
Welches Array wird in diesem Modul zurückgegeben?
function scale(n) { return this.factor * n; }
const twice = scale.bind({ factor: 2 });
const obj = { factor: 9, twice };
[obj.twice(3), twice.call({ factor: 5 }, 4)];
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
Was wird zurückgegeben?
function combine(first, ...others) {
return [first, others.length];
}
combine(...[7, 3, 8, 2]);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
Welche Werte haben items[0].done, next[1] === items[1] und next === items?
const items = [{ id: 4, done: false }, { id: 9, done: false }];
const next = items.map(item =>
item.id === 4 ? { ...item, done: true } : item
);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
Warum ist lookup.get({ code: 8 }) gleich undefined?
const key = { code: 8 };
const lookup = new Map([[key, "ready"]]);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
Welche Größen haben a.difference(b) und a.symmetricDifference(b)?
const a = new Set([2, 4, 6]);
const b = new Set([4, 8]);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
Welchen Text erzeugt dies?
JSON.stringify({ label: "Arc", count: 3 }, ["label"]);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
Dieses Modul läuft ohne Reviver-Funktion. Welche Werte haben typeof loaded.due und loaded === original?
const original = { due: new Date("2026-07-12T00:00:00.000Z") };
const loaded = JSON.parse(JSON.stringify(original));
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 4: Untersuche Aktualisierungen und Aufrufe10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
Welche Werte haben base.inner.n, clone.inner.n und copy.inner.n am Ende?
const base = { inner: { n: 2 } };
const copy = { ...base };
const clone = structuredClone(base);
Object.freeze(base);
copy.inner.n = 7;
clone.inner.n = 9;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
Welches Array gibt Object.keys(data) zurück?
const data = { z: 1, "10": 2, "02": 3, "2": 4, a: 5 };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
Was ist totalG und ändert eine Änderung von heavy.massG auch load.items[1].massG?
const load = { items: [
{ massG: 120, qty: 2 },
{ massG: 300, qty: 1 }
] };
const heavy = load.items.find(x => x.massG > 200);
const totalG = load.items.reduce((s, x) => s + x.massG * x.qty, 0);
heavy.massG = 350;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
Was gibt b.labels() in diesem Modul zurück?
const a = {
prefix: "A",
names: ["oak"],
labels() { return this.names.map(n => this.prefix + n); }
};
const b = { prefix: "B", names: ["elm"], labels: a.labels };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
Was ist typeof box.open?
const box = { open() { return "opened"; } };
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
Was geschieht, wenn read() und read({ prefs: null }) getrennt aufgerufen werden?
function read({ prefs: { theme = "light" } = {} } = {}) {
return theme;
}
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
Was ist tail?
const [head, ...tail] = [6, 8, 11];
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
Welche Werte haben m.size und [...m.keys()]?
const m = new Map([["p", 1], ["q", 2]]);
m.set("p", 4);
m["r"] = 5;
m.delete("q");
m.set("q", 6);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
JSON.parse('{"depthM":+7}') fehl?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
Welche Werte haben result.count und result.total?
const result = JSON.parse('{"count":"6","total":12}',
(key, value) => key === "count" ? Number(value) : value
);
result.total += result.count;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Set 5: Kombiniere Datenentscheidungen und Umwandlungsregeln10 Übungsfragen
Speichere diese Einheit, um jede Antwort zu sehen und jedes Set zu üben.
Frage 1 von 10
Was ist Object.hasOwn(record, "old") nach diesen Anweisungen?
const record = { old: undefined };
delete record.old;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 2 von 10
Welche Werte haben a === b, a.left === a.right und b.left === b.right?
const shared = { n: 1 };
const a = { left: shared, right: shared };
const b = JSON.parse(JSON.stringify(a));
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 3 von 10
Was gibt saved() zurück?
const maker = {
n: 5,
make() { return () => this.n; }
};
const other = { n: 8, make: maker.make };
const saved = other.make().bind({ n: 12 });
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 4 von 10
Was gibt fixed.apply({ offset: 30 }, [4]) zurück?
function add(a, b) { return this.offset + a + b; }
const fixed = add.bind({ offset: 2 }, 7);
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 5 von 10
Welche Werte haben a, b und rest?
let a = 3, b = 8;
[a, b] = [b, a];
const [, ...rest] = [a, b, 13];
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 6 von 10
Was ist nach publicCopy.profile.name = "New" der Wert von source.profile.name und besitzt source weiterhin secret als eigene Eigenschaft?
const source = { secret: "s", profile: { name: "Old" } };
const { secret, ...publicCopy } = source;
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 7 von 10
Was ist der endgültige Wert von counts.get("moss")?
const counts = new Map();
for (const word of ["moss", "fern", "moss", "moss"]) {
counts.set(word, (counts.get(word) ?? 0) + 1);
}
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 8 von 10
Welche Werte haben records.size und ids.size?
const x = { id: 7 };
const records = new Set([x, x, { id: 7 }]);
const ids = new Set([...records].map(r => r.id));
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 9 von 10
Was ist typeof JSON.parse(text)?
const text = JSON.stringify('{"x":3}');
Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Frage 10 von 10
"3" mit den Werten "n" und "s" getrennt erhalten. Welches Paar von Umwandlungen erhält sie bei einem Roundtrip durch JSON?Antwort zeigenAntwort ausblenden
Speichere diese Einheit, um diese Antwort zu sehen.
Hängst du bei deiner eigenen Aufgabe fest? Hausaufgabenhilfe
Schlüsselbegriffe
A
Abgeleiteter Wert
apply
format.apply(reading, ["m", 2]) übergibt dasselbe Empfängerobjekt und dieselben Werte wie format.call(reading, "m", 2).Array-Destrukturierung
const [low, high] = bounds; setzt voraus, dass bounds seinen kleineren Wert vor seinem größeren Wert bereitstellt.Array-Restelement
const [leader, ...others] = names; trennt den ersten Namen von einem Array der übrigen Namen.Arrayindexschlüssel
"3" steht in Object.keys vor "12"; "03" bleibt unter den gewöhnlichen Zeichenkettenschlüsseln.B
Berechneter Eigenschaftsname
const code = "es"; erstellt { [code]: "Hola" } eine Eigenschaft namens "es".bind
const next = meter.step.bind(meter); erstellt einen Callback, der meter als Empfängerobjekt behält.C
call
format.call(reading, "m", 2) übergibt format das Empfängerobjekt reading und zwei separate Argumente.D
Differenzmenge
active.difference(blocked) behält aktive Werte, die im Set blocked nicht vorkommen.E
Eigene Eigenschaft
Object.hasOwn({}, "toString") ist false, obwohl "toString" in {} true ist.Eigenschaft
active in { active: false } existiert, obwohl ihr Wert ein falscher boolescher Wert ist.Eigenschaftskurzschreibweise
city erstellt das Literal { city } dasselbe Feld wie { city: city }.Einfacher Funktionsaufruf im strikten Modus
f herausgelöst und in einem Modul mit f() aufgerufen, kann sie fehlschlagen, wenn sie versucht, this.name zu lesen.Einfügereihenfolge
Einrückungsargument
Empfängerobjekt
account.describe() ist account das Empfängerobjekt, das die Methode zum Lesen seiner Felder verwendet.Entliehene Methode
b.read = a.read ermöglicht b.read(), die Daten von b zu verwenden, wenn die Funktion über this liest.Escape-Sequenz
Existenz einer Eigenschaft
count: 0 besitzt weiterhin eine Eigenschaft count; eine Prüfung dieses Werts als Bedingung erkennt sie nicht.F
Flache Kopie
G
globalThis
I
Iterierbares Objekt
J
JSON
{"ready":true} beschreibt einen Datensatz, während true allein ebenfalls ein vollständiger gültiger JSON-Text ist.JSON-Zeichenkette
JSON.parse
JSON.parse liest JSON-Text und gibt den darin dargestellten JavaScript-Wert zurück; bei fehlerhaftem Text löst es einen SyntaxError aus.JSON.stringify
JSON.stringify serialisiert unterstützte JavaScript-Werte in JSON-Text und kann dabei Daten auswählen und eine lesbare Einrückung hinzufügen.JSON.stringify(settings, null, 2) schreibt eine besser lesbare Form, ohne die dargestellten Einstellungen zu ändern.K
Klammernotation
const field = "heightM"; wählt person[field] die Größenmessung der Person aus.L
Lexikalisches this
Losgelöste Methode
const read = sensor.read; behält die Funktion, aber read() übergibt sensor nicht als Empfängerobjekt.M
Map
"5" bleiben getrennte Einträge, wenn sie in derselben Map gespeichert werden.Map-Eintrag
stock.set("tea", 4) ändert einen Eintrag; stock["tea"] = 4 ändert eine gewöhnliche Eigenschaft.Map.groupBy
Map.groupBy ist eine neuere Methode, die Elemente eines iterierbaren Objekts in Arrays innerhalb einer Map gruppiert und Typ und Identität der Gruppenschlüssel erhält.Methode
tracker.advance() führt die Aktion von tracker aus, während das Lesen von tracker.advance eine Funktion zurückgibt.Methodenkurzschreibweise
reset() { this.n = 0; } definiert eine Aktion ohne separaten Doppelpunkt und ohne das Schlüsselwort function.Methodenverkettung
list.add("a").add("b") funktioniert, wenn der erste Aufruf ein Objekt mit der nächsten add-Methode zurückgibt.N
Nullish-Coalescing-Operator
settings.volume ?? 1 behält eine ausdrücklich angegebene Lautstärke von null bei, während settings.volume || 1 sie ersetzt.O
Object.freeze
Object.freeze verhindert das Hinzufügen, Löschen und Ändern eigener Eigenschaften eines Objekts, friert aber verschachtelte Objekte nicht ein.Object.fromEntries
Object.fromEntries erstellt aus Schlüssel-Wert-Paaren ein Objekt und ist daher nach einer Transformation von Einträgen oder einer kompatiblen Map nützlich.Object.groupBy
Object.groupBy ist eine neuere Methode, die Elemente eines iterierbaren Objekts unter vom Callback ausgewählten Schlüsseln in Arrays eines Objekts ohne Prototyp gruppiert.Objekt-Rest
const { password, ...publicRecord } = user; lässt user unverändert und schließt password aus der Kopie aus.Objekt-Spread
{ ...base, active: true } kopiert base und liefert danach den endgültigen Wert für active.Objektdestrukturierung
const { city, tempC } = reading; erstellt zwei lokale Variablen aus einem Wetterdatensatz.Objektidentität
id: 9 sind beim Vergleich mit === trotz übereinstimmender Daten ungleich.Objektliteral
const reading = { tempC: 22 }; erstellt einen Datensatz mit einer Temperaturmessung.Optionale Verkettung
record.owner?.name erlaubt einen fehlenden owner, ohne zu versuchen, einen Namen aus undefined zu lesen.Optionsobjekt
{ color, size } entgegennimmt, erlaubt Aufrufern anzugeben, was jede Einstellung bedeutet, ohne eine feste Reihenfolge einzuhalten.P
Partielle Anwendung
multiply.bind(null, 4) erstellt eine Funktion, die ihr nächstes Argument mit vier multipliziert.Pfeilfunktions-Wrapper
() => counter.tick() an map sorgt dafür, dass jeder Callback-Aufruf tick über das Objekt counter aufruft.Punktnotation
profile.name wählt immer die Eigenschaft namens "name" aus, selbst wenn eine Variable namens name existiert.R
Referenz
const backup = record; bietet einen weiteren Weg zu record, ohne dessen Felder zu kopieren.replacer-Parameter
Restparameter
function total(...values) kann reduce auf values anwenden, auch wenn der Aufruf keine Argumente übergibt.Reviver-Funktion
JSON.parse-Callback, der Werte nach ihren Kindwerten transformiert und sie mithilfe seiner Rückgabewerte ersetzt oder entfernt.Roundtrip
S
Schlüssel-Wert-Paar
Object.entries({ lake: 5 }) erzeugt [["lake", 5]], bereit für eine Schleife über Schlüssel und Wert.Schnittmenge
Serialisierung
Set
"ready" zweimal hinzugefügt, bleibt ein Wert erhalten; werden zwei separate übereinstimmende Datensätze hinzugefügt, bleiben beide erhalten.Sichere Ganzzahl
Spread für iterierbare Objekte
Math.max(...measurements) übergibt jedes Arrayelement als separates Argument an die Funktion.Standardwert bei der Destrukturierung
const { count = 2 } = { count: null }; bleibt das ausdrücklich angegebene null trotz des Standardwerts erhalten.structuredClone
Strukturprüfung
Symmetrische Differenz
SyntaxError
JSON.parse übergeben wurde.T
Teilmenge
this
Tiefe Kopie
structuredClone bleibt das ursprüngliche Feld unverändert, wenn du ein kopiertes verschachteltes Feld bearbeitest.toJSON
U
Umbenennungsmuster
const { title: label } = page; erstellt label, ohne eine Variable namens title zu deklarieren.Unveränderliche Aktualisierung
Ü
Übersprungene Position
const [, second] = colors; überspringt die erste Farbe und benennt nur den nächsten gelieferten Wert.V
Vereinigungsmenge
Verschachtelte Daten
report.readings[0].tempC liest eine Liste, ihren ersten Datensatz und dann ein Temperaturfeld.Verschachteltes Muster
const { owner: { name } } = item; benötigt ein owner-Objekt und deklariert nur name.W
WeakMap
WeakSet
Z
Zirkuläre Referenz
record.self = record führt dazu, dass das gewöhnliche JSON.stringify für diesen Datensatz einen TypeError auslöst.Zugehörigkeitsprüfung
map.has(key) kann einen vorhandenen Eintrag finden, selbst wenn map.get(key) undefined zurückgibt.Über diese Einheit
Erstelle deine eigenen Lernmaterialien
Mach aus deinen Notizen, Folien und Dokumenten Lernleitfäden, Übungsfragen, Karteikarten und 6 weitere Tools.