Objektorientierung
Erzeugen von Objekten
Objekte können erzeugt werden über
- ein Objekt-Literal (JSON) (siehe unten)
- eine Konstruktor-Funktion, die mit
newaufgerufen wird - eine Factory-Funktion, die ohne
newaufgerufen wird
Konvention
- Konstruktor-Funktionen fangen mit Großbuchstaben an
- Factory-Funktionen fangen mit Kleinbuchstaben an
Beispiel: Objekt-Literal
let schulze = {
name: "Schulze, Herbert",
geboren: "4.5.1954",
details: function() {
return "Name: " + this.name
+ ", geboren: " + this.geboren;
}
};
log(schulze.details());
Beispiel: Konstruktor-Funktion
function Mitarbeiter(name, geboren) {
this.name = name;
this.geboren = geboren;
this.details = function() {
return "Name: " + this.name
+ ", geboren: " + this.geboren;
};
}
let meier = new Mitarbeiter("Meier, Franz", "1.5.1972");
let mueller = new Mitarbeiter("Müller, Peter", "8.11.1981");
log(meier.details());
log(mueller.details());
Beispiel: Factory-Funktion
function makeMitarbeiter(name, geboren) {
let that = new Object();
that.name = name;
that.geboren = geboren;
that.details = function() {
return "Name: " + this.name
+ ", geboren: " + this.geboren; };
return that;
}
let meier = makeMitarbeiter("Meier, Franz", "1.5.1972");
let mueller = makeMitarbeiter("Müller, Peter", "8.11.1981");
log(meier.details());
log(mueller.details());
function makeMitarbeiter(name, geboren) {
return {
name: name,
geboren: geboren,
details: function() {
return "Name: " + this.name
+ ", geboren: " + this.geboren;
}
};
}
let meier = makeMitarbeiter("Meier, Franz", "1.5.1972");
let mueller = makeMitarbeiter("Müller, Peter", "8.11.1981");
log(meier.details());
log(mueller.details());
Objektbasierend
JavaScript kannte ursprünglich keine Klassen, sondern nur Objekte
- alles in JavaScript ist ein Objekt (auch Funktionen)
- Objekte erben von Objekten (prototypische Vererbung)
Konstruktor-Funktion als "Klasse"
In Java
- Klasse legt die Struktur der erzeugten Objekte fest
- Alle erzeugten Objekte haben denselben Aufbau
In JavaScript
- Konstruktorfunktion legt Struktur der erzeugten Objekte fest
- Erzeugte Objekte können unterschiedlichen Aufbau haben
- Objekte gehören zu einer Klassen, wenn sie dieselbe Konstruktorfunktion hatten
Prototype
- Zu jeder Funktion gehört ein Prototyp (prototype object)
- Zugriff über
Funktionsname.prototype - Wird die Funktion als Konstruktor (mit
new) verwendet, dann hat das erzeugte Objekt eine Referenz zum Prototypen - Sind Attribute und Funktionen nicht im Objekt definiert, dann werden sie im Prototypen gesucht
- Der Prototyp legt fest, zu welcher Klasse ein Objekt gehört
Beispiel: Java-Klasse
public class Mitarbeiter {
public String name;
public int alter;
public Mitarbeiter(String name, int alter) {
this.name = name;
this.alter = alter;
}
}
Mitarbeiter mi = new Mitarbeiter("Hans", 28);
Beispiel: JavaScript Konstruktor
function Mitarbeiter(name, alter) {
this.name = name;
this.alter = alter;
}
let mi = new Mitarbeiter("Hans", 28);
log(mi instanceof Mitarbeiter); // true
log(mi instanceof Object); // true
log(mi instanceof Date); // false
Beispiel: Vererbung in Java
public class Manager extends Mitarbeiter {
public String abteilung;
public Manager(String name, int alter, String abteilung) {
super(name, alter);
this.abteilung = abteilung;
}
}
Manager ma = new Manager("Franz", 37, "Webentwicklung");
Beispiel: Vererbung in JavaScript
function Manager(name, alter, abteilung) {
Mitarbeiter.call(this, name, alter);
this.abteilung = abteilung;
}
Manager.prototype = Object.create(Mitarbeiter.prototype);
Manager.prototype.constructor = Manager;
let ma = new Manager("Franz", 37, "Webentwicklung");
log(ma instanceof Manager); // true
log(mi instanceof Mitarbeiter); // true
ES6-Klassen
Seit ES6 kann man die Klasse explizit machen und muss nicht mehr über die Prototypen gehen
- Schlüsselwort
class constructor(...)für den Konstruktorextendsfür Vererbung
class Mitarbeiter {
constructor(name, alter) {
this.name = name;
this.alter = alter;
}
toString() {
return `name=${this.name}, alter=${this.alter}`;
}
}
let mi = new Mitarbeiter("Egon", 33);
ES6-Vererbung
class Manager extends Mitarbeiter {
constructor(name, alter, abteilung) {
super(name, alter);
this.abteilung = abteilung;
}
}
let ma = new Manager("Paul", 42, "Buchhaltung");
log(ma instanceof Manager); // true
log(mi instanceof Mitarbeiter); // true
Kapselung und Information-Hiding
- JavaScript kennt keine Zugriffsbeschränkungen (geplant für die Zukunft)
- Alle Attribute eines Objektes sind immer erreichbar
- Information-Hiding kann trotzdem erreicht werden
- Man verwendet eine Factory-Methode
- Methode erzeugt ein Objekt für die privaten Variablen
- Methode erzeugt ein Objekt für die öffentlichen Funktionen
- Dem privaten Objekt werden alle privaten Variablen und privaten Funktionen hinzugefügt
- Das öffentliche Objekt greift auf die privaten Daten zu (was es wegen der Sichtbarkeit der Daten innerhalb der Funktion darf)
- Das öffentliche Objekt wird zurückgegeben
Beispiel: Kapselung
function erzeugeTier(name, my) {
let that = {}; // leeres Objekt anlegen
let secret = {}; // leeres Objekt anlegen
secret.name = name;
that.getName = function() { return secret.name; };
that.setName = function(name) { secret.name = name; };
return that;
}
let hund = erzeugeTier("Hasso");
log(hund.getName());
hund.setName("Archibald");
log(hund.secret.name); // secret.name ist nicht sichtbar
Was ist JSON?
JSON: JavaScript Object Notation
- JavaScript kennt Objekt-Literale
- Idee: Objekt-Literale als Textdateien austauschen ⇒ JSON
Vorteile
- deutlich kompakter als XML
- fester Bestandteil der Sprache, kein Parser nötig
- auch für andere Programmiersprachen verfügbar, z. B. Java, C, C#, PHP …
Arrays mit JSON
Deklaration von Arrays mit JSON
- Liste von Elementen, durch Komma getrennte
- umrahmt von eckigen Klammern []
- Syntax:
[element1, element2, element3 ...]
let monate = ["Januar", "Februar", "März", "April", "Juni"];
let prim = [1, 2, 3, 5, 7, 11, 13];
let bools = [true, false, false, true];
Objektliterale in JavaScript
- Liste von Schlüssel-Wert-Paaren in Klammern { }
- Syntax:
{ key1: value1, key2: value2 ... }
let student = {
name: "Meier, Peter",
alter: 25,
note: 1.0,
adresse: {
strasse: "Hauptstrasse 42",
plz: 68259,
ort: "Mannheim"
}
};
let student = {
name: "Meier, Peter",
alter: 25,
note: 1.0,
adresse: {
strasse: "Hauptstrasse 42",
plz: 68259,
ort: "Mannheim"
}
};
log(student.name);
log(student.adresse.plz);
log(student.adresse.ort);
Alternativer Syntax für Objekte
- JavaScript-Objekte können auch als assoziatives Array aufgefasst werden
- Syntax:
{ "key1": "value1", "key2": "value2" ... }
let student = {
"name": "Meier, Peter",
"alter": 25,
"note": 1.0,
"adresse": {
"strasse": "Hauptstrasse 42",
"plz": 68259,
"ort": "Mannheim"
}
};
let student = {
"name": "Meier, Peter",
"alter": 25,
"note": 1.0,
"adresse": {
"strasse": "Hauptstrasse 42",
"plz": 68259,
"ort": "Mannheim"
}
};
log(student["name"]);
log(student["adresse"]["plz"]);
Funktionen in Objektliteralen
- Im Objekt-Literal können auch Funktionen zugewiesen werden
- Syntax:
{ name: function() { } ... }
let student = {
name: "Meier, Peter",
alter: 25,
altern: function() { this.alter++; }
};
log(student.alter);
student.altern();
log(student.alter);
Serialisierung
Über die Klasse JSON können Objekte serialisiert und deserialisiert werden
JSON.stringify(obj)→ Object zu JSON-StringJSON.parse(str)→ JSON-String zu Objekt
let o = {
frage: "Unbekannt",
antwort: 42
};
let s = JSON.stringify(o);
log(s);
let s = '{ "text": "ein text" }';
let o = JSON.parse(s);
log(o.text);