Objektorientierung
Ein Objekt ist ein allgemein gehaltener Datentyp. Objekte können Sie mittels JavaScript selbst erstellen. Zu den
bereits existierenden Objekt-Datentypen (auch als globale Objekte bezeichnet) von JS zählen Boolean
,
Number
, String
und Array
. Weitere globale Objekte, bei welchen es sich jedoch nicht um
Objekt-Datentypen handelt, sind z. B. Date
und Math
. Objekte können Variablen (sogenannte Eigenschaften bzw.
Objekteigenschaften) und Funktionen (sogenannte Objektfunktionen)
enthalten. Vereinfacht gesagt ist ein Objekt also dazu gedacht, mehrere Werte innerhalb eines Datentyps und somit
innerhalb einer Variablen zu speichern. Objekte können dabei auf zwei verschiedene Arten erstellt werden.
Die erste Variante, die wir vorstellen werden, sind die Einzelobjekte. Einzelobjekte können ohne weiteres nicht mehrmals
genutzt werden. Verwendet werden solche Objekte z. B. innerhalb einer Funktion, um bestimmte Daten besser „zusammen zu halten“.
Um ein Einzelobjekt zu erzeugen, notieren wir das Schlüsselwort new
, gefolgt von dem Objektdatentyp Object
.
var computer = new Object();
Nun haben wir ein formloses Objekt, auf welches wir nun mittels des Punktoperators .
auf dessen Eigenschaften
und Funktionen zugreifen können. Bevor wir auf dessen Eigenschaften und Funktionen lesend oder aufrufend zugreifen, müssen
wir diese natürlich erst zuweisen. Dies sieht dann wie folgt aus:
var computer = new Object(); computer.betriebssystem = "Windows 7"; computer.starteComputer = function () { document.write("Computer wird gestartet ..."); }; // Betriebssystem ausgeben document.write(computer.betriebssystem + "<br />"); // Funktion aufrufen computer.starteComputer();
Um ein Objekt zu erzeugen, gibt es ebenfalls noch eine Kurzschreibweise. An Stelle ein Objekt mit dem new
-Schlüsselwort
zu instanziieren (so nennt sich der Vorgang der Objekterzeugung), können wir auch einfach nur ein Paar von geschweiften
Klammern notieren. Dies sieht wie folgt aus:
var computer = { };
Der Vorteil dieser Variante ist, dass hier ganz einfach Eigenschaften und Funktionen direkt bei der Instanziierung zugewiesen werden
können. Hierfür wird bei der Zuweisung nicht das bekannte Gleichheitszeichen =
, sondern ein Doppelpunkt :
verwendet. Des Weiteren wird die Zuweisung nicht mit einem Semikolon ;
abgeschlossen, sondern mit einem Komma ,
.
Das Komma dient lediglich zur Trennung von mehreren Zuweisungen und kann bei der letzten Zuweisung somit weggelassen werden. Das
Beispiel von weiter oben, lässt sich dadurch nun wie folgt ersetzen:
var computer = { betriebssystem : "Windows 7", starteComputer : function () { document.write("Computer wird gestartet ..."); } }; // Betriebssystem ausgeben document.write(computer.betriebssystem + "<br />"); // Funktion aufrufen computer.starteComputer();
Alle Objekte werden mittels einer Referenz an andere Variablen, Funktionen oder ähnliches weitergegeben. Haben wir also nun eine zweite
Variable namens computer2
und weisen dieser den Wert der Variable computer
zu, so enthält computer2
nicht etwa eine Kopie von computer
, sondern enthält exakt das gleiche Objekt. Dies kommt daher, da in computer
und computer2
lediglich eine Referenz zu einem gewissen Speicherbereich gespeichert ist. Diese Referenz ist als Wert anzusehen
und wurde bei der Zuweisung von der einen auf die andere Variable übertragen. Nehmen wir nun an, wir ändern jetzt am Objekt computer2
die Eigenschaft betriebssystem
, so ist dadurch auch automatisch der Wert der Eigenschaft betriebssystem
des Objekts
computer
geändert. Das folgende Beispiel erläutert dieses Szenario nochmals:
var computer = { betriebssystem : "Windows 7" }; var computer2 = computer; computer2.betriebssystem = "Windows 10"; alert(computer.betriebssystem); // Gibt "Windows 10" aus
Objekteigenschaften
Objekteigenschaften sind die „Variablen von Objekten“. Zugewiesen werden können diese, wie bereits oben gezeigt, mit dem Punktoperator
.
oder direkt bei der Instanziierung (siehe Beispiel). Dabei ist darauf zu achten, dass hier kein Semikolon am Ende notiert
wird, da es sich hier nicht um ein Statement, sondern lediglich um eine Zuweisung von Eigenschaften und Funktionen (auch Methoden genannt)
zu einem Objekt handelt. Eigenschaften können „von außen“ gelesen, aber auch gesetzt werden.
var computer = { marke : "Acer", modell : "Aspire E15", betriebssystem : "Windows 7" }; document.write(computer.marke + " " + computer.modell + " mit " + computer.betriebssystem);
Objektfunktionen
Objektfunktionen (auch Objektmethoden genannt) werden in Form eines Funktionsausdrucks angegeben. Wie bei den Eigenschaften auch, können Funktionen direkt bei der Instanziierung sowie im Nachhinein hinzugefügt werden. Das folgende Beispiel zeigt die Zuweisung von Funktionen direkt beim Instanziieren des Objekts:
var computer = { betriebssystem : "Windows 7", benutzer : "admin", passwort : "123", stateComputer : function () { document.write(this.betriebssystem + " wird gestartet ...<br />"); }, stoppeComputer : function () { document.write(this.betriebssystem + " wird heruntergefahren ...<br />"); }, benutzerLogin : function (name, passwort) { if (name == this.benutzer && passwort == this.passwort) document.write("Benutzer " + name + " erfolgreich angemeldet!<br />"); else document.write("Benutzername oder Passwort falsch!<br />"); } }; computer.stateComputer(); computer.benutzerLogin("admin", ""); computer.benutzerLogin("admin", "123"); computer.stoppeComputer();
Das im obigen Beispiel verwendete Schlüsselwort this
erlaubt den expliziten Zugriff auf das aktuelle Objekt. Die Notation des
this
-Schlüsselworts ist notwendig, sodass der Interpreter weiß, um was für eine Variable o. Ä. es sich handelt. Wird this
weggelassen, so geht der Interpreter davon aus, dass es sich um eine lokale Variable, eine globale Variable oder einen Übergabeparameter
(bei einer Funktion) handelt. this
verweist immer auf das aktuelle Objekt. Wird es also innerhalb eines Objekts
(z. B. in einer Objektfunktion) verwendet, so verweist this
auf dessen Objekt. Wird this
außerhalb eines Objekts
verwendet, so verweist this
auf das globale Objekt window
, welches zum sogenannten BOM gehört
(dazu später mehr). Im obigen Beispiel könnte jedoch z. B. this.betriebssystem
durch computer.betriebssystem
ersetzt werden.
Konstruktorfunktion
Eine Konstruktorfunktion (engl. constructor function) erlaubt es, ein Objekt so zu gestalten, dass wir es mehrmals und auch an
unterschiedlichen Stellen wiederverwenden können. Hierfür deklarieren wir eine Funktion, dessen Funktionsnamen dem Objektnamen entspricht.
Die Parameter der Funktion sind als Konstruktorparameter anzusehen und können so wie Funktionsparameter gestaltet werden. Innerhalb der
Konstruktorfunktion werden üblicherweise neben dem dazugehörigen Initialisierungs-Programmcode, auch Objekteigenschaften und Objektfunktionen
angegeben. Nachdem wir unser Objekt nun erstellt haben, müssen wir dieses nur noch instanziieren. Dies geht über die bekannte Variante mit dem
new
-Schlüsselwort, gefolgt von dem definierten Objektnamen. Dies sieht dann z. B. so aus:
function Computer(betriebssystem, benutzerName = "admin", benutzerPasswort = "123") { // Eigenschaften this.betriebssystem = betriebssystem; this.benutzer = benutzerName; this.passwort = benutzerPasswort; // Funktionen this.stateComputer = function () { document.write(this.betriebssystem + " wird gestartet ...<br />"); }; this.stoppeComputer = function () { document.write(this.betriebssystem + " wird heruntergefahren ...<br />"); }; this.benutzerLogin = function (name, passwort) { if (name == this.benutzer && passwort == this.passwort) document.write("Benutzer " + name + " erfolgreich angemeldet!<br />"); else document.write("Benutzername oder Passwort falsch!<br />"); }; // Code document.write("Computer erstellt!<br />"); } // Beispiele zur Verwendung des Objekts document.write("Computer 1:<br />"); var computer1 = new Computer("Windows 7", "admin", "admin"); computer1.stateComputer(); computer1.benutzerLogin("admin", "123"); computer1.stoppeComputer(); document.write("<br />"); document.write("Computer 2:<br />"); var computer2 = new Computer("Windows 10"); computer2.stateComputer(); computer2.benutzerLogin("admin", "123");
Wichtig: Beim obigen Beispiel und generell bei allen Konstruktorfunktionen ist das this
-Schlüsselwort unersetzlich.
Übrigens: Bei der Objektdeklaration mittels einer Konstruktorfunktion ist es möglich, eine Art von privaten Variablen zu erstellen.
Auf private Variablen kann man innerhalb eines Objekts zugreifen. Ein Zugriff „von außen“ auf diese Variablen ist jedoch nicht möglich. Private
Variablen werden innerhalb der Konstruktorfunktion wie „einfache Variablen“ (mittels var
-Schlüsselwort) angegeben.
function Computer() { var betriebssystem = "Windows 7"; // Dies ist eine private Eigenschaft } var meinComputer = new Computer(); alert(meinComputer.betriebssystem); // Gibt undefined aus
Objekt-Arrays
Arrays mit Objekten als Werte sind von Arrays mit z. B. Zahlen als Werte in erster Linie nicht zu unterscheiden. Jedoch gibt es bei Arrays
mit Objekten einige Probleme. Das Problem bei der Verwendung von Objekt-Arrays ist, dass Suchfunktionen wie indexOf()
und
lastIndexOf()
in den meisten Fällen nicht mehr funktionieren. Dies kommt daher, da wir zumeist die Referenz auf das Objekt nicht
mehr haben. Eine Suche mit einem Objekt, welches die gleichen Werte hat, bleibt erfolglos, da die Referenz eine andere ist. Die Suche sollte
also lediglich mit Hilfe der Eigenschaften durchgeführt werden. Eine solche Funktion gibt es jedoch nicht, d. h. wir müssen die Suche
manuell ausführen. Dies kann z. B. mittels einer Schleife durchgeführt werden. Das folgende Beispiel zeigt das Ergebnis der erfolglosen
Suche mit indexOf()
und anschließend die „manuelle Suche“ mittels einer Schleife:
var computerListe = new Array( { marke : "Acer", modell : "Aspire E15", betriebssystem : "Windows 7" }, { marke : "Asus", modell : "R752SA", betriebssystem : "Windows 10" }, { marke : "Toshiba", modell : "Satellite L70", betriebssystem : "Windows 10" } ); document.write("Suche mit indexoOf: " + computerListe.indexOf( { marke : "Asus", modell : "R752SA", betriebssystem : "Windows 10" } ) + "<br />"); for (var i = 0; i < computerListe.length; i++) { if (computerListe[i].marke == "Asus" && computerListe[i].modell == "R752SA" && computerListe[i].betriebssystem == "Windows 10") { document.write("Suche mit Schleife: " + i); break; } }
Benötigen wir lediglich das Objekt selbst (z. B. zum Abrufen weiterer Eigenschaften oder aufrufen von Objektfunktionen) und nicht dessen
Index im Array, so können wir das Array mittels der filter()
-Funktion filtern. Daraus resultiert dann ein wesentlich kürzerer
Code im Vergleich zu der oben programmierten Schleife.
computerListe.filter(x => x.marke == "Asus" && x.modell == "R752SA" && x.betriebssystem == "Windows 10");
Übrigens: Die Sortierung von Objekt-Arrays mit Hilfe der sort()
-Funktion funktioniert ebenfalls nicht mehr wie gewohnt,
da der Interpreter nicht weiß, wie er die Objekte sortieren soll. Um Objekte weiterhin sortieren zu können, müssen wir der
sort()
-Funktion als Parameter eine Funktion übergeben. Diese Sortierungsfunktion erhält immer zwei Übergabewerte
(Wert a und Wert b) und kann dann einen negativen Wert, 0 oder einen positiven Wert zurückgeben. Ein negativer Wert bedeutet, dass a vor b
einsortiert werden muss. 0 bedeutet, dass die Objekte a und b gleich sind. Ein positiver Wert führt dazu, dass a nach b einsortiert wird.
Objekterweiterung
Der Aufbau von Objekten, welcher mit einer Konstruktorfunktion deklariert wurden oder sogar zum Sprachvorrat von JavaScript gehören, kann im
Nachhinein mittels der einfachen Zuweisung, wie wir diese bei Einzelobjekten angewendet haben, nicht mehr erweitert werden. Doch natürlich
können auch solche Objekte erweitert werden. Hierfür müssen wir den sogenannten Prototypen verändern. Hierzu notieren wir den Objektnamen,
gefolgt von einem Punkt, dem Schlüsselwort prototype
und einem weiteren Punkt. Anschließend muss lediglich noch der Name der neuen
Funktion bzw. Eigenschaft angegeben werden und dieser ein Funktionsausdruck oder ein Wert zugewiesen werden.
Das folgende Beispiel erweitert das Objekt Number
und somit den Datentyp Number
um die Funktion padNumber()
,
mit welcher es nun möglich ist, Zahlen mit führenden Nullen darzustellen. Diese Variante der Objekterweiterung ist sehr nützlich und wird gerade
zum Erweitern der Funktionen von vorhandenen Datentypen verwendet. Wie Sie im Beispiel sehen können, gibt this
innerhalb des
Funktionsausdrucks die Zahl des Objekts zurück.
Number.prototype.padNumber = function (pad) { var str = this.toString(); while (str.length < pad) str = "0" + str; return str; }; var zahl = 12; for (var i = 0; i < 10; i++) document.write(i + ": " + zahl.padNumber(i) + "<br />");