Aufwärmen · Aufgabe 1 von 7
Zum Aufwärmen, aus Lektion B5.3: Was gibt dieser Code aus?
const base = {a: 1, b: 2};
const copy = {...base, b: 3};
console.log(copy.a, copy.b, base.b);// I2.1 · ca. 33 Min. · Aufbau
Nach dieser Lektion können Sie sagen, wo JavaScript eine Eigenschaft findet: am Objekt selbst oder weiter oben in seiner Prototypenkette. Mit Object.create bauen Sie Objekte auf einem gemeinsamen Prototyp.
Lektion 1 von 5 in I2 Objekte, Prototypen und Klassen
Danach können Sie
Aufwärmen · Aufgabe 1 von 7
const base = {a: 1, b: 2};
const copy = {...base, b: 3};
console.log(copy.a, copy.b, base.b);Vorhersagen · Aufgabe 2 von 7
const proto = {greet() { return "hello"; }};
const obj = Object.create(proto);
console.log(Object.keys(obj).length, obj.greet());Üben · Aufgabe 3 von 7
const animal = {speak() { return "..."; }};
const cat = Object.____(animal);Üben · Aufgabe 4 von 7
Üben · Aufgabe 5 von 7
const proto = {color: "red"};
const a = Object.create(proto);
const b = Object.create(proto);
a.color = "blue";
console.log(a.color, b.color, proto.color);Denksport · Aufgabe 6 von 7
const proto = {shared: 1};
const obj = Object.create(proto);
obj.own = 2;
const seen = [];
for (const key in obj) seen.push(key);
console.log(seen.join(","), Object.keys(obj).join(","));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
animal enthält einen Standardlaut und eine Methode speak(). cat und fish werden mit Object.create(animal) erzeugt, beide verweisen also darauf. cat bekommt einen eigenen sound, der den Standard überdeckt; fish behält den geerbten. Das Programm prüft dann die Verweise und die Arten von Eigenschaften und folgt der Kette bis zu ihrem Ende.
main.js
// A prototype with a shared method.
const animal = {
sound: "...",
speak() {
return `${this.name} says ${this.sound}`;
}
};
// Two objects that link to it.
const cat = Object.create(animal);
cat.name = "Mia";
cat.sound = "meow"; // an own property: it shadows animal.sound
const fish = Object.create(animal);
fish.name = "Bubbles";
console.log(cat.speak());
console.log(fish.speak());
console.log(Object.getPrototypeOf(cat) === animal);
console.log(Object.hasOwn(cat, "sound"), Object.hasOwn(fish, "sound"));
console.log("speak" in fish, Object.hasOwn(fish, "speak"));
console.log(cat.speak === fish.speak);
console.log(Object.keys(cat));
// The chain goes on: animal links to Object.prototype, which links to null.
console.log(Object.getPrototypeOf(animal) === Object.prototype);
console.log(Object.getPrototypeOf(Object.prototype));
Ausführen mit
node main.jsAusgabe
Mia says meow
Bubbles says ...
true
true false
true false
true
[ 'name', 'sound' ]
true
nullTab 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
Schreiben Sie describe(obj, key). Die Funktion gibt "own" zurück, wenn key eine eigene Eigenschaft von obj ist, "inherited", wenn obj key nur über seine Prototypenkette bekommt, und "missing", wenn der Schlüssel gar nicht gefunden wird. Der Starter verwendet nur den Operator in und nennt deshalb geerbte Eigenschaften eigene.
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: Geerbte Schlüssel kommen als eigene zurück. Welche Prüfung ist nur für das Objekt selbst wahr?
Object.hasOwn(obj, key) ist nur für eigene Eigenschaften true; key in obj ist für eigene und geerbte true.
Prüfen Sie zuerst Object.hasOwn und geben Sie "own" zurück, dann key in obj und geben Sie "inherited" zurück, sonst "missing".
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
export function describe(obj, key) {
if (Object.hasOwn(obj, key)) return "own";
if (key in obj) return "inherited";
return "missing";
}
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
export function describe(obj, key) {
if (key in obj) return "own";
return "missing";
}
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {describe} from './main.js';
test('Eine Eigenschaft am Objekt selbst ist eigen', () => {
const got = describe({name: 'Ada'}, 'name');
assert.equal(got, 'own', `describe({name}, 'name') ergab ${got}`);
});
test('Eine Eigenschaft vom Prototyp ist geerbt', () => {
const child = Object.create({kind: 'fruit'});
const got = describe(child, 'kind');
assert.equal(got, 'inherited', `describe(child, 'kind') ergab ${got}`);
});
test('toString an einem einfachen Objekt ist geerbt', () => {
const got = describe({}, 'toString');
assert.equal(got, 'inherited', `describe({}, 'toString') ergab ${got}`);
});
test('Ein unbekannter Schlüssel fehlt', () => {
const got = describe({}, 'colour');
assert.equal(got, 'missing', `describe({}, 'colour') ergab ${got}`);
});
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
makeCounter(start) soll einen Zähler zurückgeben, dessen increment() seinen count um eins erhöht und ihn zurückgibt. Die Methode soll nur einmal auf counterProto liegen und nicht an jedem Zähler. Der Starter gibt jedem Zähler eine eigene Kopie von increment. Bauen Sie den Zähler mit Object.create(counterProto) und geben Sie ihm nur einen eigenen count.
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: increment funktioniert, ist aber eine eigene Eigenschaft jedes Zählers. Wo sollte es stattdessen liegen?
Object.create(counterProto) liefert ein leeres Objekt, das increment erbt.
const counter = Object.create(counterProto); counter.count = start; return counter;
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
export const counterProto = {
increment() {
this.count += 1;
return this.count;
}
};
export function makeCounter(start) {
const counter = Object.create(counterProto);
counter.count = start;
return counter;
}
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
export const counterProto = {
increment() {
this.count += 1;
return this.count;
}
};
export function makeCounter(start) {
return {
count: start,
increment() {
this.count += 1;
return this.count;
}
};
}
main.test.js
import {test} from 'node:test';
import assert from 'node:assert/strict';
import {counterProto, makeCounter} from './main.js';
test('increment erhöht um eins und gibt den neuen count zurück', () => {
const counter = makeCounter(5);
counter.increment();
const got = counter.increment();
assert.equal(got, 7, `zwei Aufrufe von increment ab 5 ergaben ${got}`);
});
test('Der Prototyp eines Zählers ist counterProto', () => {
const counter = makeCounter(0);
assert.equal(Object.getPrototypeOf(counter) === counterProto, true, 'Object.getPrototypeOf(counter) sollte counterProto sein');
});
test('increment ist geerbt, keine eigene Eigenschaft', () => {
const counter = makeCounter(0);
assert.equal(Object.hasOwn(counter, 'increment'), false, 'jeder Zähler hat sein eigenes increment; es sollte von counterProto kommen');
});
test('Zwei Zähler behalten ihren eigenen count', () => {
const a = makeCounter(0);
const b = makeCounter(10);
a.increment();
assert.deepEqual([a.count, b.count], [1, 10], `die Zählerstände sind ${a.count} und ${b.count}`);
});
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 animal = {speak() { return "..."; }};
const cat = Object.create();
console.log(cat.speak());
Was Node.js ausgibt
TypeError: Object prototype may only be an Object or null: undefinedWarum, und die Lösung
Object.create braucht als erstes Argument das Objekt, auf das verwiesen werden soll; es kopiert keines und rät auch keines. Übergeben Sie den Prototyp: Object.create(animal). Wollen Sie wirklich ein Objekt ganz ohne Prototyp, sagen Sie es ausdrücklich mit Object.create(null).
const stock = Object.create(null);
stock.apples = 3;
console.log(stock.hasOwnProperty("apples"));
Was Node.js ausgibt
TypeError: stock.hasOwnProperty is not a functionWarum, und die Lösung
hasOwnProperty wird von Object.prototype geerbt. Ein mit Object.create(null) erzeugtes Objekt hat keinen Prototyp, also auch kein hasOwnProperty. Verwenden Sie stattdessen die statische Methode, die für jedes Objekt funktioniert: Object.hasOwn(stock, "apples").
const proto = {
hello: () => `I am ${this.name}`
};
const a = Object.create(proto);
a.name = "Ada";
console.log(a.hello());
Was Node.js ausgibt
TypeError: Cannot read properties of undefined (reading 'name')Warum, und die Lösung
Eine Pfeilfunktion hat kein eigenes this; sie übernimmt this vom umgebenden Code. Am Anfang eines Moduls ist das undefined, this.name scheitert also, egal welches Objekt hello aufgerufen hat. Schreiben Sie geteilte Methoden mit der Methodensyntax, hello() { return `I am ${this.name}`; }, damit this das Objekt vor dem Punkt ist.
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.