Und automatisch werden alle öffentlichen/geschützten Methoden, Eigenschaften, Felder usw. der Super-Klasse Teil der Sub-Klasse, die bei Bedarf überschrieben werden kann.
Schau mal hier: stackoverflow.com/questions/1908443/…
– Darin Dimitrow
21. Januar 10 um 7:33 Uhr
Funktioniert dieser Crockford-Weg noch? ZParenizor.inherits(Parenizor);
– Pascha Skender
7. April 16 um 17:26 Uhr
Siehe auch: JavaScript-Erweiterungsklasse
– user56reinstatemonica8
7. August 16 um 11:01 Uhr
Christian C. Salvado
In JavaScript haben Sie nicht Klassen aber Sie können Vererbung und Verhaltenswiederverwendung auf viele Arten erreichen:
Pseudo-klassische Vererbung (durch Prototyping):
function Super () {
this.member1 = 'superMember1';
}
Super.prototype.member2 = 'superMember2';
function Sub() {
this.member3 = 'subMember3';
//...
}
Sub.prototype = new Super();
Sollte mit verwendet werden new Operator:
var subInstance = new Sub();
Funktionsanwendung oder “Konstruktorverkettung”:
function Super () {
this.member1 = 'superMember1';
this.member2 = 'superMember2';
}
function Sub() {
Super.apply(this, arguments);
this.member3 = 'subMember3';
}
Dieser Ansatz sollte auch mit dem verwendet werden new Operator:
var subInstance = new Sub();
Der Unterschied zum ersten Beispiel besteht darin, dass wenn wir apply das Super Konstrukteur zum this Objekt drin Sub, fügt es die zugewiesenen Eigenschaften hinzu this an Super, direkt auf der neuen Instanz, z subInstance enthält die Eigenschaften member1 und member2 direkt (subInstance.hasOwnProperty('member1') == true;).
Im ersten Beispiel werden diese Eigenschaften über die erreicht Prototyp-Kette, sie existieren auf einem internen [[Prototype]] Objekt.
Parasitäre Vererbung oder Power Constructors:
function createSuper() {
var obj = {
member1: 'superMember1',
member2: 'superMember2'
};
return obj;
}
function createSub() {
var obj = createSuper();
obj.member3 = 'subMember3';
return obj;
}
Dieser Ansatz basiert im Wesentlichen auf “Objekterweiterung”, Sie müssen die nicht verwenden new Betreiber, und wie Sie sehen können, die this Schlüsselwort ist nicht beteiligt.
var subInstance = createSub();
ECMAScript 5. Auflage. Object.create Methode:
// Check if native implementation available
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {} // empty constructor
F.prototype = o; // set base object as prototype
return new F(); // return empty object with right [[Prototype]]
};
}
var superInstance = {
member1: 'superMember1',
member2: 'superMember2'
};
var subInstance = Object.create(superInstance);
subInstance.member3 = 'subMember3';
Das obige Verfahren ist eine prototypische Vererbungstechnik, die von vorgeschlagen wurde Crockford.
Objektinstanzen erben von anderen Objektinstanzen, das war’s.
Diese Technik kann besser sein als eine einfache “Objekterweiterung”, da die geerbten Eigenschaften nicht über alle neuen Objektinstanzen kopiert werden, da die Base Objekt wird als festgelegt [[Prototype]] des erweitert Objekt, im obigen Beispiel subInstance enthält physikalisch nur die member3 Eigentum.
Verwenden Sie keine Instanzen für die Vererbung – verwenden Sie ES5 Object.create() oder ein Brauch clone() Funktion (zB mercurial.intuxication.org/hg/js-hacks/raw-file/tip/clone.js ), um direkt vom Prototypobjekt zu erben; siehe die Kommentare zu stackoverflow.com/questions/1404559/… für eine Erklärung
– Christoph
21. Januar ’10 um 9:00 Uhr
Danke @Christoph, das wollte ich gerade erwähnen Object.create Methode 🙂
– Christian C. Salvado
21. Januar 10 um 15:18 Uhr
Dies ist keine ordnungsgemäße Vererbung, da Sie die Instanzmitglieder von Super auf dem Prototyp von Sub haben werden. Daher teilen sich alle Instanzen des Subs dasselbe member1 variabel, was überhaupt nicht erwünscht ist. Natürlich können sie es umschreiben, aber das macht einfach keinen Sinn. github.com/dotnetwise/Javascript-FastClass ist eine bessere Zuckerlösung.
– Adaptabi
18. April 14 um 7:52 Uhr
Hallo @CMS, könnten Sie bitte erklären, warum ich im ersten Beispiel eine Instanz der übergeordneten Klasse erstellen muss, um die Vererbung für die Unterklasse einzurichten? Ich rede von dieser Zeile: Sub.prototype = new Super();. Was ist, wenn beide Klassen während der Skriptausführung niemals verwendet werden? Es sieht nach einem Leistungsproblem aus. Warum muss ich eine übergeordnete Klasse erstellen, wenn die untergeordnete Klasse nicht tatsächlich verwendet wird? Können Sie das bitte erläutern? Hier ist die einfache Demonstration des Problems: jsfiddle.net/slavafomin/ZeVL2 Danke!
– Slawa Fomin II
15. Mai 14 um 18:53 Uhr
In allen Beispielen – außer dem letzten – gibt es eine „Klasse“ für Super und eine „Klasse“ für Sub, und dann erstellen Sie eine Instanz von Sub. Können Sie ein vergleichbares Beispiel für das Object.create-Beispiel hinzufügen?
– Lukas
6. August 14 um 18:24 Uhr
Björn
Ich habe geändert, wie ich das jetzt mache, ich versuche zu vermeiden, Konstruktorfunktionen und ihre zu verwenden prototype Eigentum, aber meine alte Antwort von 2010 ist immer noch ganz unten. Ich bevorzuge jetzt Object.create(). Object.create ist in allen modernen Browsern verfügbar.
Das sollte ich beachten Object.create ist gewöhnlich viel langsamer als zu verwenden new mit einem Funktionskonstruktor.
//The prototype is just an object when you use `Object.create()`
var Base = {};
//This is how you create an instance:
var baseInstance = Object.create(Base);
//If you want to inherit from "Base":
var subInstance = Object.create(Object.create(Base));
//Detect if subInstance is an instance of Base:
console.log(Base.isPrototypeOf(subInstance)); //True
Einer der großen Vorteile der Verwendung von Object.create besteht darin, dass a übergeben werden kann Eigenschaften definieren Argument, das Ihnen eine erhebliche Kontrolle darüber gibt, wie auf Eigenschaften in der Klasse zugegriffen und aufgezählt werden kann, und ich verwende auch Funktionen, um Instanzen zu erstellen, diese dienen in gewisser Weise als Konstruktoren, da Sie am Ende eine Initialisierung durchführen können, anstatt nur die zurückzugeben Beispiel.
var Base = {};
function createBase() {
return Object.create(Base, {
doSomething: {
value: function () {
console.log("Doing something");
},
},
});
}
var Sub = createBase();
function createSub() {
return Object.create(Sub, {
doSomethingElse: {
value: function () {
console.log("Doing something else");
},
},
});
}
var subInstance = createSub();
subInstance.doSomething(); //Logs "Doing something"
subInstance.doSomethingElse(); //Logs "Doing something else"
console.log(Base.isPrototypeOf(subInstance)); //Logs "true"
console.log(Sub.isPrototypeOf(subInstance)); //Logs "true
function Base ( ) {
this.color = "blue";
}
function Sub ( ) {
}
Sub.prototype = new Base( );
Sub.prototype.showColor = function ( ) {
console.log( this.color );
}
var instance = new Sub ( );
instance.showColor( ); //"blue"
Wie wäre es mit dem sub.prototype.constructor-Wert? Ich denke, es sollte auch auf Unterwert eingestellt werden.
– maximal
26. März 13 um 3:22 Uhr
Abgesehen davon, dass Sie reservierte Schlüsselwörter (‘super’) als Klassennamen verwenden, konnte ich Ihr Beispiel nicht zum Laufen bringen: jsbin.com/ixiyet/8/edit
– MONSDAR
9. Juni 13 um 14:43 Uhr
@MONsDaR Ich habe es in Base umbenannt
– Björn
12. Juni 13 um 19:11 Uhr
Wenn ich benutze alert() um was zu sehen instance.showColor() Rücksendungen bekomme ich noch undefined. jsbin.com/uqalin/1
– MONSDAR
14. Juni 13 um 7:15 Uhr
@MONsDaR Das liegt daran, dass es Konsolenprotokolle enthält und nichts zurückgibt, das die Warnung anzeigen soll. Sehen Sie eine Rücksendeanweisung in showColor?
– Björn
14. Juni 13 um 14:54 Uhr
Merlin
Für diejenigen, die diese Seite 2019 oder später erreichen
Mit der neuesten Version des ECMAScript-Standards (ES6), können Sie das Schlüsselwort verwenden class.
Beachten Sie, dass die Klassendefinition keine reguläre ist object; daher gibt es keine Kommas zwischen Klassenmitgliedern. Um eine Instanz einer Klasse zu erstellen, müssen Sie die verwenden new Stichwort. Um von einer Basisklasse zu erben, verwenden Sie extends:
class Vehicle {
constructor(name) {
this.name = name;
this.kind = 'vehicle';
}
getName() {
return this.name;
}
}
// Create an instance
var myVehicle = new Vehicle('rocky');
myVehicle.getName(); // => 'rocky'
Um von einer Basisklasse zu erben, verwenden Sie extends:
class Car extends Vehicle {
constructor(name) {
super(name);
this.kind = 'car'
}
}
var myCar = new Car('bumpy');
myCar.getName(); // => 'bumpy'
myCar instanceof Car; // => true
myCar instanceof Vehicle; // => true
Von der abgeleiteten Klasse aus können Sie super von jedem Konstruktor oder jeder Methode verwenden, um auf ihre Basisklasse zuzugreifen:
Verwenden Sie zum Aufrufen des übergeordneten Konstruktors super().
Um ein anderes Mitglied anzurufen, verwenden Sie beispielsweise super.getName().
Zur Verwendung von Klassen gehört mehr. Wer tiefer in das Thema einsteigen möchte, dem empfehle ich „Klassen in ECMAScript 6“ von Dr. Axel Rauschmayer.*
Unter der Haube, class und extends ist (sehr nützlicher) Syntaxzucker für die Prototypkette: stackoverflow.com/a/23877420/895245
– Ciro Santilli 新疆再教育营六四事件法轮功郝海东
20. November 16 um 12:21 Uhr
nur zu Ihrer Information ‘instance.name’ hier ‘mycar.name’ gibt den Namen der Klasse zurück. Dies ist ein Standardverhalten von ES6 und ESnext. Hier wird für mycar.name ‘Vehicle’ zurückgegeben.
– Shiljo Paulson
8. August 17 um 13:16 Uhr
Nun, in JavaScript gibt es keine “Klassenvererbung”, sondern nur “Prototypenvererbung”. Sie erstellen also keine Klasse „Lkw“ und markieren sie dann als Unterklasse von „Automobil“. Stattdessen erstellen Sie ein Objekt „Jack“ und sagen, dass es „John“ als Prototyp verwendet. Wenn John weiß, wie viel “4+4” ist, dann weiß es Jack auch.
Ich schlage vor, Sie lesen hier Douglas Crockfords Artikel über prototypische Vererbung: http://javascript.crockford.com/prototypal.html Er zeigt auch, wie Sie JavaScript dazu bringen können, eine “Look-alike”-Vererbung wie in anderen OO-Sprachen zu haben, und erklärt dann, dass dies tatsächlich bedeutet, Javascript auf eine Weise zu brechen, für die es nicht vorgesehen war.
Lukas
Dieses Zitat finde ich am aufschlussreichsten:
Im Wesentlichen ein JavaScript “Klasse” ist nur ein Function-Objekt, das als Konstruktor dient, plus ein angehängtes Prototyp-Objekt. (Quelle: Guru Katz)
Ich verwende lieber Konstruktoren als Objekte, daher bin ich ein Fan der hier von CMS beschriebenen Methode der „pseudoklassischen Vererbung“. Hier ist ein Beispiel für Mehrfachvererbung mit einer Prototypkette:
// Lifeform "Class" (Constructor function, No prototype)
function Lifeform () {
this.isLifeform = true;
}
// Animal "Class" (Constructor function + prototype for inheritance)
function Animal () {
this.isAnimal = true;
}
Animal.prototype = new Lifeform();
// Mammal "Class" (Constructor function + prototype for inheritance)
function Mammal () {
this.isMammal = true;
}
Mammal.prototype = new Animal();
// Cat "Class" (Constructor function + prototype for inheritance)
function Cat (species) {
this.isCat = true;
this.species = species
}
Cat.prototype = new Mammal();
// Make an instance object of the Cat "Class"
var tiger = new Cat("tiger");
console.log(tiger);
// The console outputs a Cat object with all the properties from all "classes"
console.log(tiger.isCat, tiger.isMammal, tiger.isAnimal, tiger.isLifeform);
// Outputs: true true true true
// You can see that all of these "is" properties are available in this object
// We can check to see which properties are really part of the instance object
console.log( "tiger hasOwnProperty: "
,tiger.hasOwnProperty("isLifeform") // false
,tiger.hasOwnProperty("isAnimal") // false
,tiger.hasOwnProperty("isMammal") // false
,tiger.hasOwnProperty("isCat") // true
);
// New properties can be added to the prototypes of any
// of the "classes" above and they will be usable by the instance
Lifeform.prototype.A = 1;
Animal.prototype.B = 2;
Mammal.prototype.C = 3;
Cat.prototype.D = 4;
console.log(tiger.A, tiger.B, tiger.C, tiger.D);
// Console outputs: 1 2 3 4
// Look at the instance object again
console.log(tiger);
// You'll see it now has the "D" property
// The others are accessible but not visible (console issue?)
// In the Chrome console you should be able to drill down the __proto__ chain
// You can also look down the proto chain with Object.getPrototypeOf
// (Equivalent to tiger.__proto__)
console.log( Object.getPrototypeOf(tiger) ); // Mammal
console.log( Object.getPrototypeOf(Object.getPrototypeOf(tiger)) ); // Animal
// Etc. to get to Lifeform
Die Javascript-Vererbung unterscheidet sich ein wenig von Java und PHP, da es keine wirklichen Klassen gibt. Stattdessen verfügt es über Prototypobjekte, die Methoden und Mitgliedsvariablen bereitstellen. Sie können diese Prototypen verketten, um Objektvererbung bereitzustellen. Das häufigste Muster, das ich bei der Recherche zu dieser Frage gefunden habe, ist auf beschrieben Mozilla-Entwicklernetzwerk. Ich habe ihr Beispiel aktualisiert, um einen Aufruf einer Superklassenmethode einzufügen und das Protokoll in einer Warnmeldung anzuzeigen:
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
// superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
log += 'Shape moved.n';
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
// Override method
Rectangle.prototype.move = function(x, y) {
Shape.prototype.move.call(this, x, y); // call superclass method
log += 'Rectangle moved.n';
}
var log = "";
var rect = new Rectangle();
log += ('Is rect an instance of Rectangle? ' + (rect instanceof Rectangle) + 'n'); // true
log += ('Is rect an instance of Shape? ' + (rect instanceof Shape) + 'n'); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
alert(log);
Persönlich finde ich die Vererbung in Javascript umständlich, aber dies ist die beste Version, die ich gefunden habe.
Gleichstrom
Sie können nicht (im klassischen Sinne). Javascript ist eine prototypische Sprache. Sie werden feststellen, dass Sie in Javascript niemals eine “Klasse” deklarieren; Sie definieren lediglich den Zustand und die Methoden eines Objekts. Um eine Vererbung zu erzeugen, nehmen Sie ein Objekt und erstellen einen Prototyp davon. Der Prototyp wird um neue Funktionalität erweitert.
.
7580400cookie-checkWie erbt man von einer Klasse in Javascript?yes
Verknüpfung : crockford.com/javascript/inheritance.html , oder phrogz.net/JS/Classes/OOPinJS2.html
– Haim Jewgi
21. Januar 10 um 7:32 Uhr
Schau mal hier: stackoverflow.com/questions/1908443/…
– Darin Dimitrow
21. Januar 10 um 7:33 Uhr
Funktioniert dieser Crockford-Weg noch? ZParenizor.inherits(Parenizor);
– Pascha Skender
7. April 16 um 17:26 Uhr
Siehe auch: JavaScript-Erweiterungsklasse
– user56reinstatemonica8
7. August 16 um 11:01 Uhr