Aufwärmen · Aufgabe 1 von 7
Zum Aufwärmen: Was gibt dieser Code aus?
const book = { title: "Dune", year: 1965 };
console.log(book.title, book.pages);// B5.3 · ca. 30 Min. · Einstieg
Nach dieser Lektion bauen und ändern Sie Objekte, entpacken sie per Destrukturierung, kopieren und mischen sie mit Spread und lesen verschachtelte Werte sicher.
Danach können Sie
Aufwärmen · Aufgabe 1 von 7
const book = { title: "Dune", year: 1965 };
console.log(book.title, book.pages);Vorhersagen · Aufgabe 2 von 7
const a = { size: "M", colour: "red" };
const b = { ...a, size: "L" };
console.log(a.size, b.size, b.colour);Üben · Aufgabe 3 von 7
const item = { price: 4, name: "tea" };
const key = "price";
console.log(item[____]);Üben · Aufgabe 4 von 7
Üben · Aufgabe 5 von 7
const stock = { apples: 3, pears: 0 };
console.log(Object.keys(stock), Object.values(stock));Denksport · Aufgabe 6 von 7
const original = { name: "Ada", address: { city: "Berlin" } };
const copy = { ...original };
copy.name = "Grace";
copy.address.city = "Paris";
console.log(original);Anwenden · Aufgabe 7 von 7
Prüfen Sie Ihr Ergebnis anhand dieser Liste
Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.
Ausgearbeitetes Beispiel
Ein Profilobjekt, auf alle Arten dieser Lektion verwendet: Es wird mit Punkt und mit Klammern gelesen, geändert, mit in und Object.hasOwn geprüft, mit Object.entries durchlaufen, mit Umbenennung und Standardwert entpackt und mit Spread gemischt. Der letzte Teil zeigt die flache Kopie: Der neue Name der Kopie bleibt in der Kopie, ihre neue Stadt erreicht aber das Original.
main.js
// A user profile: read, change, loop, unpack, copy and merge.
const user = { name: "Ada", city: "Berlin", tags: ["admin"] };
console.log(user.name, user["city"], user.age);
const key = "city";
user[key] = "Munich";
user.age = 36;
delete user.tags;
console.log(user);
console.log("age" in user, Object.hasOwn(user, "tags"));
for (const [k, v] of Object.entries(user)) {
console.log(`${k} = ${v}`);
}
const { name, age: years, role = "guest" } = user;
console.log(name, years, role);
const defaults = { theme: "light", lang: "en" };
const settings = { ...defaults, lang: "de" };
console.log(settings, defaults);
const original = { name: "Ada", address: { city: "Berlin" } };
const copy = { ...original };
copy.name = "Grace";
copy.address.city = "Paris";
console.log(original);
console.log(original.phone?.mobile, original.address?.city);
Ausführen mit
node main.jsAusgabe
Ada Berlin undefined
{ name: 'Ada', city: 'Munich', age: 36 }
true false
name = Ada
city = Munich
age = 36
Ada 36 guest
{ theme: 'light', lang: 'de' } { theme: 'light', lang: 'en' }
{ name: 'Ada', address: { city: 'Paris' } }
undefined ParisTab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.
Übung 1 von 2
label(product) soll Name, Doppelpunkt, Preis und Währung zurückgeben, etwa Tea: 3 EUR. Hat das Produkt keine Währung, nehmen Sie EUR. cityOf(user) soll die Stadt des Benutzers zurückgeben, user.address.city, oder "unknown", wenn er keine Adresse hat. Der Starter gibt bei fehlender Währung undefined aus und stoppt bei fehlender Adresse mit einem TypeError. Beheben Sie beides: Destrukturierung mit Standardwert hilft beim ersten, ?. und ?? beim zweiten.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.
Führen Sie die Tests aus: Das Label endet auf undefined, weil das Produkt keinen Schlüssel currency hat.
Entpacken Sie den Parameter mit einem Standardwert: function label({ name, price, currency = "EUR" }).
user.address ist bei Bo undefined. user.address?.city ergibt undefined statt eines Fehlers, und ?? "unknown" ersetzt es.
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
// "Tea: 3 EUR"; the currency is EUR when the product has none.
export function label({ name, price, currency = "EUR" }) {
return name + ": " + price + " " + currency;
}
// The user's city, or "unknown" when there is no address.
export function cityOf(user) {
return user.address?.city ?? "unknown";
}
Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.js
// "Tea: 3 EUR"; the currency is EUR when the product has none.
export function label(product) {
return product.name + ": " + product.price + " " + product.currency;
}
// The user's city, or "unknown" when there is no address.
export function cityOf(user) {
return user.address.city;
}
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {label, cityOf} from './main.js';
test('label verwendet die Währung des Produkts', () => {
const got = label({ name: 'Tea', price: 3, currency: 'USD' });
assert.equal(got, 'Tea: 3 USD', `label hat ${JSON.stringify(got)} zurückgegeben, erwartet "Tea: 3 USD"`);
});
test('label nimmt EUR, wenn das Produkt keine Währung hat', () => {
const got = label({ name: 'Milk', price: 1.2 });
assert.equal(got, 'Milk: 1.2 EUR', `label hat ${JSON.stringify(got)} zurückgegeben, erwartet "Milk: 1.2 EUR"`);
});
test('cityOf liest die Stadt aus der Adresse', () => {
const got = cityOf({ name: 'Ada', address: { city: 'Berlin' } });
assert.equal(got, 'Berlin', `cityOf hat ${JSON.stringify(got)} zurückgegeben, erwartet "Berlin"`);
});
test('cityOf ergibt unknown, wenn es keine Adresse gibt', () => {
const got = cityOf({ name: 'Bo' });
assert.equal(got, 'unknown', `cityOf hat ${JSON.stringify(got)} zurückgegeben, erwartet "unknown"`);
});
package.json
{
"type": "module"
}
package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.
Programm ausführen:
node main.jsPrüfungen ausführen (learnrun.js muss im selben Ordner liegen):
node --testlearnrun.js herunterladenÜbung 2 von 2
withQuantity(item, quantity) soll ein neues Objekt mit allen Schlüsseln von item und der angegebenen quantity zurückgeben und item unverändert lassen. copyCart(cart) soll eine Kopie eines Warenkorbs { owner, items } zurückgeben, die neue Artikel bekommen kann, ohne den ursprünglichen Warenkorb zu ändern. Der Starter ändert item selbst, und seine Warenkorbkopie teilt sich das Array items. Beheben Sie beides mit Spread.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.
Führen Sie die Tests aus: Nach withQuantity(item, 5) hat der ursprüngliche Artikel die Menge 5. Die Zuweisung an item ändert das Objekt des Aufrufers.
Bauen Sie stattdessen ein neues Objekt: { ...item, quantity }. Der spätere Schlüssel gewinnt, und quantity ist die Kurzform von quantity: quantity.
{ ...cart } ist flach: Die Kopie teilt sich cart.items. Geben Sie ihr ein eigenes Array: { ...cart, items: [...cart.items] }.
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
// A new object: item with this quantity. item stays unchanged.
export function withQuantity(item, quantity) {
return { ...item, quantity };
}
// A copy of the cart whose items can change on their own.
export function copyCart(cart) {
return { ...cart, items: [...cart.items] };
}
Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.js
// A new object: item with this quantity. item stays unchanged.
export function withQuantity(item, quantity) {
item.quantity = quantity;
return item;
}
// A copy of the cart whose items can change on their own.
export function copyCart(cart) {
return { ...cart };
}
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {withQuantity, copyCart} from './main.js';
test('withQuantity gibt den Artikel mit der neuen Menge zurück', () => {
const got = withQuantity({ name: 'Tea', quantity: 1 }, 3);
assert.deepEqual(got, { name: 'Tea', quantity: 3 }, `withQuantity hat ${JSON.stringify(got)} zurückgegeben, erwartet {"name":"Tea","quantity":3}`);
});
test('withQuantity lässt den ursprünglichen Artikel unverändert', () => {
const item = { name: 'Tea', quantity: 1 };
withQuantity(item, 5);
assert.equal(item.quantity, 1, `die Menge des ursprünglichen Artikels wurde ${item.quantity}, erwartet war, dass sie 1 bleibt`);
});
test('copyCart kopiert owner und items', () => {
const got = copyCart({ owner: 'Ada', items: ['tea'] });
assert.deepEqual(got, { owner: 'Ada', items: ['tea'] }, `copyCart hat ${JSON.stringify(got)} zurückgegeben`);
});
test('Ein Artikel in der Kopie lässt den ursprünglichen Warenkorb in Ruhe', () => {
const cart = { owner: 'Ada', items: ['tea'] };
const copy = copyCart(cart);
copy.items.push('milk');
assert.deepEqual(cart.items, ['tea'], `die items des ursprünglichen Warenkorbs wurden zu ${JSON.stringify(cart.items)}, erwartet ["tea"]`);
});
package.json
{
"type": "module"
}
package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.
Programm ausführen:
node main.jsPrüfungen ausführen (learnrun.js muss im selben Ordner liegen):
node --testlearnrun.js herunterladenconst prices = { tea: 3, milk: 1.2 };
for (const price of prices) {
console.log(price);
}
Was Node.js ausgibt
TypeError: prices is not iterableWarum, und die Lösung
for...of durchläuft Arrays und Strings, aber ein einfaches Objekt ist nicht iterierbar. Machen Sie zuerst ein Array daraus: Object.values(prices) für die Werte, Object.keys(prices) für die Namen oder Object.entries(prices) für beides: for (const [name, price] of Object.entries(prices)) { … }.
function greet({ name }) {
return "Hello, " + name;
}
console.log(greet());
Was Node.js ausgibt
TypeError: Cannot destructure property 'name' of 'undefined' as it is undefined.Warum, und die Lösung
greet entpackt sein erstes Argument, aber der Aufruf übergibt keines, also versucht es, name aus undefined zu lesen. Übergeben Sie ein Objekt, greet({ name: "Ada" }), oder geben Sie dem Parameter ein Standardobjekt: function greet({ name } = {}) { … }; name ist dann undefined statt eines Fehlers und kann einen eigenen Standardwert haben: { name = "friend" } = {}.
const user = { name: "Ada" };
console.log(user.address.city);
Was Node.js ausgibt
TypeError: Cannot read properties of undefined (reading 'city')Warum, und die Lösung
user hat keine address, also ist user.address undefined, und city aus undefined zu lesen ist ein TypeError. Die Meldung nennt den Schlüssel, der gelesen werden sollte. Wenn ein Teil fehlen kann, nutzen Sie Optional Chaining: user.address?.city ergibt undefined. Mit ?? kommt ein Ersatzwert dazu: user.address?.city ?? "unknown".
JavaScript im Browser: die eigene Engine Ihres Browsers in einem abgeschotteten Worker. Syntaxfehler findet acorn 8.18.0, MIT. Lizenz und Quellcode
5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.
Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.