Vererbung
Vererbung ist der Prozess, durch den ein Objekt auf einem anderen basieren kann. Dadurch können die Objekte die Eigenschaften des jeweils anderen teilen.
Ich habe den Prototyp Hero
erstellt und ihn verwendet, um ein neues Objekt namens superman
zu erstellen. Aber wir haben mit diesem Objekt noch nichts vor. Also kümmern wir uns darum, indem wir eine weitere Funktion mit dem Namen dialogue
erstellen.
function dialogue() {
console.log('I am ' + this.name);
}
Aber wenn wir unseren Code jetzt ausführen, wird nichts passieren, weil diese Funktion nicht weiß, wie der Name wirklich lautet. Dazu müssen wir
Ich möchte, dass diese neue Funktion die gleichen Eigenschaften hat wie die Hero
. Anstatt sie in dieser Funktion aufzuschreiben, können wir JavaScript einfach sagen, dass es sie vom Hero
-Prototyp erben soll.
Dies ist mit Hilfe der prototype
-Eigenschaft möglich, die in jedem Objekt in JavaScript verfügbar ist.
Indem wir dialogue
auf Hero.prototype
setzen, haben wir es allen Instanzen von Hero
zur Verfügung gestellt.
Differentielle Vererbung
JavaScript verfügt auch über ein anderes Vererbungsmodell, die sogenannte „differentielle Vererbung“. Bei diesem Modell werden die Methoden nicht vom Elternteil zum Kind kopiert. Stattdessen gibt es eine Verbindung zwischen den Kindern und ihrem Elternobjekt.
Hier hat superman
eigentlich keine eigene Methode namens dialogue()
. Aber wie funktioniert dann superman.dialogue()
?
Wenn die JavaScript-Engine im Code auf superman.dialogue()
stößt, sucht sie nach der Eigenschaft dialogue
innerhalb des Objekts superman
. Wenn sie keine findet, sucht sie in der Prototypenkette nach der übergeordneten Eigenschaft Hero.prototype
von superman
. Dort findet es Hero.prototype.dialogue
und ruft es mit einem this
auf, das an superman
gebunden ist.
Object.create()
Wir können dies noch exklusiver gestalten, indem wir eine neue Klasse für Superman
erstellen, die die Eigenschaften des Hero
-Prototyps erbt. Wir können dies tun, indem wir den Prototyp von Superman
dem Hero
-Prototyp wie folgt zuweisen:
function Superman() {}
Superman.prototype = Hero.prototype
Aber dadurch werden Superman
und Hero
einfach gleich. Was wir wirklich brauchen, ist ein neues Objekt, das auf dem Hero
-Prototyp basiert. Seit ES5 verfügt JavaScript über eine eingebaute Funktion namens Object.create()
. Wir verwenden sie hier wie folgt:
Superman.prototype = Object.create(Hero.prototype);
Damit wird ein neues leeres Objekt erstellt, das auf dem Prototyp Hero
basiert und dem Prototyp Superman
zugewiesen wird. Auf alle Eigenschaften des Hero
-Prototyps kann nun über den Superman
-Prototyp zugegriffen werden. Anstatt also new Hero
aufzurufen, können wir new Superman
aufrufen, und alles wird weiterhin so funktionieren, wie es sollte.
Wenn Sie sich die Ausgabe jedoch genauer ansehen, werden Sie feststellen, dass ein undefined
darin enthalten ist. Das liegt daran, dass der Hero
derzeit ein Konstruktor nur für sich selbst ist. Wir müssen call
die Eigenschaften von Hero
innerhalb des Superman
Prototyps angeben.
function Superman() {
Hero.call(this, 'Superman', 'Clark Kent', 'Krypton')
}
Lassen Sie uns einen weiteren Konstruktor mit dem Namen MarvelMovies
wie unten gezeigt erstellen:
function MarvelMovies(movieName, releaseYear) {
this.movieName = movieName;
this.releaseYear = releaseYear;
}
Wenn eine Funktion als Konstruktor verwendet wird, bezieht sich this
auf das neue Objekt, das wir erstellen. In diesem Konstruktor habe ich also movieName
und releaseYear
als Argumente genommen und diese Werte den Eigenschaften movieName
und releaseYear
unserer neuen MarvelMovies
-Instanz namens avengers
zugewiesen.
var avengers = new MarvelMovies("avengers", 2012);
Ich werde dann eine neue Methode mit dem Namen output
für diesen Prototyp erstellen, wie unten gezeigt:
MarvelMovies.prototype.output = function() {
return "Movie: " + this.movieName + " Released in " + this.releaseYear;
}
console.log(avengers.output());
Zukunftsvererbung
Ein wirklich großartiger Aspekt der Vererbung ist, dass JavaScript es Ihnen ermöglicht, die Eigenschaften einer Klasse zu ändern oder zu erweitern, selbst nachdem Sie sie definiert haben.
JavaScript wird den Prototyp nachschlagen, wenn Sie versuchen, auf Eigenschaften eines Objekts zuzugreifen. Sie können also Klassen zur Laufzeit ändern!
Um dies zu veranschaulichen, erstellen wir ein Array wie unten gezeigt:
var numbers = ;
Array.prototype.shuffle = function() {
return this.sort(function() {
return Math.round( Math.random() * 2) - 1;
});
};
console.log(numbers.shuffle());
Hier existierte das Array numbers
vor dem Array Array.prototype.shuffle
. Aber in JavaScript werden die Eigenschaften in der Prototypenkette nach oben durchlaufen. Aus diesem Grund erhält das Array immer noch Zugriff auf die neue Methode shuffle
, da es auf Array.prototype
existiert, wenn wir versuchen, es zu verwenden.
Einfach ausgedrückt haben wir ein Array erstellt, dann zurückgegangen und allen Arrays Zugriff auf eine neue Methode gegeben.