vorige Präsentation: Events und Closures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation Regular Expressions
Hinter den “Klassen” von Javascript versteckt sich in Wirklichkeit an anderer Mechanismus: Prototypen.
Wie im vorigen Kapitel kurz erläutert ist jede Funktion in Javascript auch ein Objekt.
Man kann zur Funktion Attribute speichern. Es gibt ein Attribut mit einer speziellen Bedeutung
bei einer Konstruktor-Funktion: das Attribut prototype
: prototype verweist auf ein Objekt,
in dem weitere Methoden und Attribute für alle Objekte die mit diesem Konstruktor erzeugt wurden
gespeichert werden.
// Konstruktor function Studiengang(name, seit, hs) { this.name = name; this.seit = seit; this.hs = hs; } // Zwei Attribute am prototyp des Konstruktors Studiengang.prototype.min = 2; Studiengang.prototype.max = 42; // Eine Methode am prototyp des Konstruktors Studiengang.prototype.toString = function () { return "Studiengang " + this.name + " (seit " + this.seit + " @ " + this.hs.name + ")"; } typeof Studiengang; // function! mmtb = new Studiengang( "BSc MultiMediaTechnology", 2008, hs ); mmtm = new Studiengang( "MSc MultiMediaTechnology", 2011, hs ); mmtb.toString(); // findet toString Methode des // Prototypen und ruft sie auf mmtb.min // findet min Attribut des Prototypen // gibt Wert 2 mmtb.min=5 // speichert Wert 5 im Objekt selbst mmtb.min // gibt jetzt Wert 5 mmtm.min // findet min Attribut des Prototypen, // gibt Wert 2
Wird ein Attribut oder eine Methode an einem Objekt gesucht, und kann direkt am Objekt nicht gefunden werden, dann durchsucht der Javascript-Interpreter als nächstes den Prototypen des Konstruktors.
Attribute direkt im Objekt überschreiben die Attribute des Prototypen: im Beispiel
wird das Attribut min
direkt im Objekt gefunden, hier ist kein Zugriff auf den Protypen nötig.
Dies war nur ein erster Einstieg in die objektorientierte Programmierung mit Javascript. Details zu einigen wichtigen Befehlen in der Javascript-Referenz bei Mozilla:
Eine Konstruktur-Funktion kann von einem Objekt erben, und zwar über den Prototypen:
// ----- Pet --------- function Pet() { this.status = "sleeping"; } Pet.prototype.log = function() { console.log("i am " + this.status + ". " + this.word + "!"); } // ----- Mammal --------- function Mammal() { this.legs = 4; } Mammal.prototype = new Pet(); Mammal.prototype.constructor = Mammal; // ----- Dog -------- function Dog( b ) { this.breed = b; this.word = "wau"; } Dog.prototype = new Mammal(); Dog.prototype.constructor = Dog; Dog.prototype.sit = function() { this.status.set("sitting"); } d = new Dog("beagle"); d.word // direkt im Objekt gespeichert d.legs // im Prototyp von Dog gespeichert // (einem Mammal-Objekt) d.status // im Prototyp von mammal gespeichert // (einem Pet-Objekt)
Diese Vererbungs-Kette über die Prototypen nenn man auf english “prototype chain”.
Achtung: die Konstruktoren der übergeordenten Objekte werden nur einmal aufgerufen, das kann zu unerwarteten Effekten führen:
// ----- Pet --------- function Pet() { this.status = new Status(); } // .... Mammal.prototype = new Pet(); // .... d1 = new Dog("Beagle"); d2 = new Dog("Schnauzer"); d1.status === d2.status // es gibt nur ein Status-Objekt // für alle Mammals! d1.hasOwnProperty('status'); // false d1.status = new Status('playing'); d1.status === d2.status // false d1.hasOwnProperty('status'); // true
Der Schnauzer hat einen schrecklichen Unfall, und verliert ein Bein:
d1 = new Dog("Beagle"); d2 = new Dog("Schnauzer"); d2.legs = 3; console.log(d1.legs); // 4 Beine von Mammal console.log(d2.legs); // 3 Beine d1.hasOwnProperty('legs') // ... false d2.hasOwnProperty('legs') // ... true
Doch nun geschieht ein Wunder: wenn wir mit delete
das
Attribut legs
aus d2
entfernen hat er wieder 4 Beine - weil
das im prototypen so gespeichert ist.
delete(d2.legs); console.log(d2.legs); // 4 Beine d2.hasOwnProperty('legs') // ... false
vorige Präsentation: Events und Closures | zurück zum Buch-Kapitel [esc] | Nächste Präsentation Regular Expressions
/
#