Krautkanal.com

Veröffentlicht am 2015-11-07 16:10:1 in /prog/

/prog/ 8056: Vererbung in JS

murrayswift Avatar
murrayswift:#8056

Bernd, wie vererbt man denn in Javascript nun richtig? Bislang habe ich immer Beipiel1 verwendet. Das soll zwar sehr verbreitet aber laut Stappelüberlauf und anderen falsch sein. Wenn ich Beispiel2 verwende dann können meine Car-Instanzen nicht auf die Vehicle-Eigenschaft canMove zugreifen. Bernd was genau ist der Unterschied bei den beiden Beispielen und welche Methode soll Bernd denn nun verwenden?


function Vehicle()
{
this.canMove = true;
}

function Car()
{
this.wheels = 4;
}


//Beispiel1
Car.prototype = new Vehicle();
Car.prototype.constructor = Car;

//Beispiel2
Car.prototype = Object.create(Vehicle.prototype)
Car.prototype.constructor = Car;

lisakey1986 Avatar
lisakey1986:#8057

>>8056

>Wenn ich Beispiel2 verwende dann können meine Car-Instanzen nicht auf die Vehicle-Eigenschaft canMove zugreifen.

Weil du den Parent-Konstruktor nicht aufrufst... Du müsstest in Car() ein Vehicle.call(this) o. ä. einfügen.

Beim ersten Beispiel setzt du eine Instanz als Prototype, was komisch ist, da du dann ja auch Instanz-Variablen mit drin hast.

JS hat keine Vererbung im klassichen OO-Sinn, sondern nur Prototypen. Sobald du an einem Prototyp etwas änderst, wirkt sich das auf alle Objekte aus, die von diesem "geerbt" haben. Wenn du im Konstruktor dann this.canMove = true schreibst, ist das eine Instanz-Variable, gilt also nur für die einzelne Instanz. Prototypen-Variablen und Methoden gelten hingegen immer für alle Instanzen, das ist der große Unterschied. Das kann sehr verwirrend sein, da man beides über this aufruft...

Ich würde Beispiel 2 nehmen oder gleich ES6 schreiben und mit Babel zu ES5 kompilieren, denn dann könntest du das übersichtlicher schreiben:

https://babeljs.io/docs/learn-es2015/#classes

Heißt zwar in ES6 "class", ist aber unter der Haube immer noch prototypenbasiert.

canapud Avatar
canapud:#8058

>>8057
coffeescript (auch wenn dieser Bernd nicht wirklich etwas davon hält) wäre auch eine Möglichkeit, OO-Code auf gewohnte klassenbasierte Weise zu schreiben. Sieht so ziemlich wie Ruby, aber kompiliert halt zu JS.