Object – Daten und Funktionen unter einem Namen sammeln

Objekte sind Behälter für logisch zusammen gehörende Variablen und Funktionen, die als Eigenschaften und Methoden des Objekts bezeichnet werden. Ein Javascript Object organisiert Daten, kapselt Daten und Logik nach außen ab und bietet eine einfache Schnittstelle zu seinen Elementen über seinen Namen.

Javascript Object

Object anlegen – drei Schreibweisen

Eigene Objekte werden angelegt, um Daten und Verhalten unter einem Namen zu sammeln, z.B. um einen VHS-Kurs durch den voran gesetzten Namen vhs.kurstitel, vhs.lesson, vhs.dozent, vhs.ort … erkenntlich zu machen. So entsteht eine nachvollziehbare Struktur anstelle von losen Variablen.

Ein Objekt ist eine komma-getrennte Liste von Eigenschaften mit einem Namen und einen Wert. Die Werte können Strings, Zahlen, Boolean, Arrays – von jedem Datentyp sein, auch selber wieder Objekte.

const vhs = {
	titel: "WordPress in nur 12 Stunden",
	dozent: "Mustermann",
	ort: "Kastelplatz 17 Raum 112",
	gebühr: 78,
	plätze: 13
}	   ▲     ▲
	   │     └── Wert
	   │
	   └── Eigenschaft / property

Hochkommas um die Namen der Eigenschaften wie title, num oder register sind optional – können aber die Struktur besser herausstellen. Geschmacksache.

Der letzte Eintrag braucht kein Komma; einige Javascript-Implementierungen werden sogar zickig, wenn ein Komma hinter dem letzten Element eines Objekts sitzt.

Schreibweisen von Objekten

Es gibt mehrere Vorgehen beim Erzeugen von Objekten. Eine Vorgehensweise nutzt einfach geschweifte Klammern, um ein Objekt zu initialisieren:

Die geschweiften Klammern erzeugen ein leeres Objekt. Jetzt können dem Objekt Eigenschaften mit der sogen. dot-Notation zugewiesen werden. Genauso gut lassen sich die Eigenschaften und ihre Werte direkt innerhalb der geschweiften Klammern notieren, und zusätzliche Eigenschaften nachträglich mit der dot-Notation hinzufügen.

Literal

const vhs = {
	titel: "WordPress in nur 12 Stunden",
	dozent: "Mustermann",
	ort: "Kastelplatz 17 Raum 112",
	gebühr: 78,
	plätze: 13
}
console.log ("vhs", vhs);
▼ vhs
  ▼ Object
	S dozent: "Mustermann"
	N gebühr: 78
	S ort: "Kastelplatz 17 Raum 112"
	N plätze: 13
	S titel: "WordPress in nur 12 Stunden"

Kurzschreibweise

const vhs = {};
vhs.titel = "WordPress in nur 12 Stunden";
vhs.dozent = "Mustermann";
vhs.ort = "Kastelplatz 17 Raum 112";
vhs.gebühr = 78;
vhs.plätze = 13;

console.log (vhs);
▼ vhs
  ▼ Object
	S dozent: "Mustermann"
	N gebühr: 78
	S ort: "Kastelplatz 17 Raum 112"
	N plätze: 13
	S titel: "WordPress in nur 12 Stunden"

Formell

const vhs = new Object();
vhs.titel = "WordPress in nur 12 Stunden";
vhs.dozent = "Mustermann";
vhs.ort = "Kastelplatz 17 Raum 112";
vhs.gebühr = 78;
vhs.plätze = 13;

console.log(vhs)
▼ vhs
  ▼ Object
	S dozent: "Mustermann"
	N gebühr: 78
	S ort: "Kastelplatz 17 Raum 112"
	N plätze: 13
	S titel: "WordPress in nur 12 Stunden"

Objekte mit new Object erzeugen oder einfach Literal / in Kurzschreibweise?

Die dritte Variante erzeugt das Objekt mit new Object in einem zweistufigen Prozess:

  1. Die Deklaration eines Objekts legt eine Vorlage für ein Objekt an.
  2. Der new-Operator erzeugt die Datenstruktur – man sagt auch »das Objekt wird instanziert«.

Diesen Weg wird man kaum gehen. Im Endeffekt sind die mit new Object und die in Kurzschrift oben erzeugten Objekte gleich. Lesbarer und schneller sind die einfachen Schreibweisen.

Eigenschaften und Methoden von Objekten

Eine Eigenschaft (property) eines Objekts ist ein Wert eines beliebiger Datentyps (number, string, array …) und auch selbst vom Typ Object sein kann. Ein Objekt kann zudem Funktionen enthalten (die als »Methoden« bezeichnet werden). Eine Methode für das vhs-Objekt wäre z.B. save(), um die Daten an eine Anwendung zu senden.

const vhs = {
	titel: "WordPress in nur 12 Stunden",
	dozent: "Mustermann",
	ort: "Kastelplatz 17 Raum 112",
	gebühr: 78,
	plätze: 13,
  
	async save() {
		const response = await fetch("/api/kurs.php", {
			method: "POST",
			headers: {
				"Content-Type": "application/json"
			},
			body: JSON.stringify(this)
		});
	
		const result = await response.json();
		console.log("Server-Antwort:", result);
	}
}
// Aufruf
vhs.save();

Der Zugriff auf die Elemente und auch auf Methoden läuft über den Namen des Objekts gefolgt von einem Punkt (auch als Dot bezeichnet) – gefolgt vom Namen der Variablen oder Funktion.

vhs.gebühr = 78;
oder
vhs.save();

Diese dot-Notatation kennen wir von vielen vorgefertigten Javascript Objects wie window oder document.

Um es einfach zu machen: Was außerhalb von Objekten »Variable« genannt wird, heißt innerhalb von Objekten Property oder Eigenschaft. Funktionen in Objekten bezeichnet man als Methoden.

this im Javascript Object

this braucht man in Javascript-Objekten, damit ein Objekt auf seine eigenen Daten zugreifen kann. Man könnte durchaus sagen this heißt »ich selbst« – genau dieses Objekt. Innerhalb des Objekts greift this also auf das Objekt zu – this.title auf die Bezeichnung, this.places auf die Eigenschaft places des Objekts.

const user = {
	name: "Anna",
	greet() {
		return "Hallo " + this.name;
	}
};

Objekte mit einer Factory-Funktion erzeugen

So großen Sinn scheint das Objekt nicht zu machen, denn so müsste der Quelltext jedesmal geändert werden, um einen weiteren Kurs anzulegen. Keine Spur von »Dynamik«.

Eine einfache Funktion erlöst das Skript von dieser Statik.

function createKurs({ titel, dozent, ort, gebühr, plätze }) {
	return {
		titel,
		dozent,
		ort,
		gebühr,
		plätze,

		async save() {
			const response = await fetch("objekte.php", {
				method: "POST",
				headers: {
					"Content-Type": "application/json"
				},
				body: JSON.stringify(this)
			});
		return await response.json();
		}
	};
}

So lassen sich beliebig viele Kurse als Objekt erzeugen und direkt an die Anwendung senden.

const kurs1 = createKurs({
	titel: "WordPress",
	dozent: "Mustermann",
	ort: "Raum 112",
	gebühr: 78,
	plätze: 13
});

const kurs2 = createKurs({
	titel: "JavaScript",
	dozent: "Meier",
	ort: "Raum 5",
	gebühr: 99,
	plätze: 10
});

kurs1.save();
kurs2.save();

Eine weitere Technik, Objekte nach einem Muster oder Bauplan zu erzeugen, bildet die Kontruktor-Funktion.

function Kurs(titel, dozent, ort, gebühr, plätze) {
	this.titel = titel;
	  this.dozent = dozent;
	this.ort = ort;
	this.gebühr = gebühr;
	this.plätze = plätze;
}

Die Kontruktor-Funktion wird aufgerufen mit

const kurs1 = new Kurs(
	"WordPress in nur 12 Stunden",
	"Mustermann",
	"Kastelplatz 17 Raum 112",
	78,
	13
);

Methoden gehören in den Prototype.

Kurs.prototype.save = async function () {
	const response = await fetch("objekte.php", {
		method: "POST",
		headers: {
			"Content-Type": "application/json"
		},
		body: JSON.stringify(this)
	});

	return await response.json();
};
KonstuktorFactory
kurs1.save(); const kurs = createKurs(...);

Heute werden eher Factory-Funktionen oder Javascript Klassen vorgezogen, Konstruktor-Funktionen sind selten geworden. Empfehlenswert sind Factory-Methoden, wenn ein kleines bis mittleres Projekt einfach gehalten werden soll und keine Vererbung vorgesehen ist.

Klassen werden bevorzugt, wenn viele Methoden gebraucht werden und das Projekt später erweitert werden soll.

Javascript Object für Formulare und Apps

Ein Objekt kann ein HTML-Formular mit Methoden zum Prüfen und Speichern von Eingaben abbilden:


			

Das Objekt dient hier in erster Linie dazu, die Daten unter einem Namen zu speichern. Die Factory-Funktion für das VHS-Objekt ist einfach:

function createVHS(form) {
	return {
		titel: form.vhs__title.value,
		dozent: form.vhs__dozent.value,
		ort: form.vhs__ort.value,
		gebühr: form.vhs__gebuehr.value,
		plätze: form.vhs__plaetze.value,
		beschreibung: form.vhs__beschreibung.value,
	};
}

Konstruktor-Funktionen

Mit Factory-Funktionen werden Methoden jedes Mal neu erzeugt – das kann sich zu einem Speicherproblem auswachsen. Jede Instanz hat ihre eigene Kopie von print.

function createVHS(titel) {
	return {
		titel,
		print() {
			console.log(this.titel);
		}
	};
}

Das wäre ein guter Grund, von der Factory-Funktion auf eine Konstruktor-Funktion umzusteigen. Damit wird print nur einmal im Speicher existieren.

function VHS(titel) {
	this.titel = titel;
}

VHS.prototype.print = function() {
	console.log(this.titel);
};

Optional Chaining – Optionale Verkettung

Frisch in Javascript ist Optional Chaining angekommen. Der ?-Operator hat eine zusätzliche Aufgabe bekommen und liest Eigenschaften des Objekts aus, ohne dass sich die Script-Logik darum kümmern muss, ob die Eigenschaft im Objekt vorhanden ist.

Wenn das Script eine Objekt-Eigenschaft aufruft, die nicht existiert (z.B. durch einen undefinierten Wert in der Datenbank oder aus einem API), würde ein Laufzeitfehler entstehen. Das ist aber nicht immer wünschenswert.

const planet = {
	name : "Mars",
	maße : {
		durchmesser : 6800,
		dichte : 9.93
	}
}
let inhabit = planet.maße?.bewohner;
console.log ("inhabit", inhabit);

planet.maße? existiert – das erzeugt keinen Fehler. Optional Chaining führt nicht zu einem Crash, sondern sagt: »Wenn etwas fehlt, brich ruhig ab und gib undefined zurück«. ?. bedeutet also »Daten sind optional« und wird bevorzugt dort eingesetzt, wo Daten nicht vorhanden sein müssen (z.B. APIs).

inhabit – undefined

Konstruktor-Funktionen

Die literale Notation und auch die Kurzschreibweisen machen den Scriptcode gut lesbar, sind aber nicht für jede Aufgabe geeignet. Wenn mehrere Kopien ähnlicher Objekte gebraucht werden, würde redundanter Code entstehen. Für solche Anwendungen hat Javascript eine andere Technik zur Erzeugung von Objekten – Konstruktor-Funktionen oder constructor functions. Konstruktor-Funktionen fangen per Konvention mit einem Großbuchstaben an und werden typischerweise für Datentypen eingesetzt, z.B. zur Erzeugung neuer Arrays.

let farben = new Array ("rot", "grün", "blau");
let tag    = new Date ();
let muster = new RegExp ();

Javascript-Klassen

In vielen objektorientierten Programmiersprachen wird ein Objekt durch eine Klasse deklariert. JavaScript kannte bis ECMAScript 2015 keine Klassendefinition.

Javascript class wurde ES6 vorgestellt und legt eine zusätzliche Syntax über die Prototyp-basierte Vererbung. Die neuen Javascript-Klassen vereinfachen die Syntax und den Umgang mit der Vererbung.

Suchen auf mediaevent.de