Die Frage ist ziemlich alt, aber ich habe eine mögliche Lösung erstellt, wie eine abstrakte "Klasse" erstellt und die Erstellung eines Objekts dieses Typs blockiert werden kann.
//our Abstract class
var Animal=function(){
this.name="Animal";
this.fullname=this.name;
//check if we have abstract paramater in prototype
if (Object.getPrototypeOf(this).hasOwnProperty("abstract")){
throw new Error("Can't instantiate abstract class!");
}
};
//very important - Animal prototype has property abstract
Animal.prototype.abstract=true;
Animal.prototype.hello=function(){
console.log("Hello from "+this.name);
};
Animal.prototype.fullHello=function(){
console.log("Hello from "+this.fullname);
};
//first inheritans
var Cat=function(){
Animal.call(this);//run constructor of animal
this.name="Cat";
this.fullname=this.fullname+" - "+this.name;
};
Cat.prototype=Object.create(Animal.prototype);
//second inheritans
var Tiger=function(){
Cat.call(this);//run constructor of animal
this.name="Tiger";
this.fullname=this.fullname+" - "+this.name;
};
Tiger.prototype=Object.create(Cat.prototype);
//cat can be used
console.log("WE CREATE CAT:");
var cat=new Cat();
cat.hello();
cat.fullHello();
//tiger can be used
console.log("WE CREATE TIGER:");
var tiger=new Tiger();
tiger.hello();
tiger.fullHello();
console.log("WE CREATE ANIMAL ( IT IS ABSTRACT ):");
//animal is abstract, cannot be used - see error in console
var animal=new Animal();
animal=animal.fullHello();
Wie Sie sehen können, gibt uns das letzte Objekt einen Fehler, weil das Tier im Prototyp die Eigenschaft hat abstract
. Um sicher zu sein, dass es nicht Animal ist, was Animal.prototype
ich in der Prototypenkette habe:
Object.getPrototypeOf(this).hasOwnProperty("abstract")
Ich überprüfe also, ob mein nächstgelegenes Prototypobjekt eine abstract
Eigenschaft hat. Nur Objekte, die direkt aus dem Animal
Prototyp erstellt wurden, haben diese Bedingung auf true. Die Funktion hasOwnProperty
überprüft nur die Eigenschaften des aktuellen Objekts, nicht seine Prototypen. Dies gibt uns 100% ige Sicherheit, dass die Eigenschaft hier nicht in der Prototypenkette deklariert ist.
Jedes von Object abstammende Objekt erbt die hasOwnProperty- Methode. Diese Methode kann verwendet werden, um zu bestimmen, ob ein Objekt die angegebene Eigenschaft als direkte Eigenschaft dieses Objekts hat. Im Gegensatz zum In-Operator überprüft diese Methode nicht die Prototypenkette des Objekts. Mehr dazu:
In meinem Vorschlag müssen wir uns nicht constructor
jedes Mal ändern, Object.create
wie es in der derzeit besten Antwort von @ Jordão ist.
Die Lösung ermöglicht auch das Erstellen vieler abstrakter Klassen in Hierarchien. Wir müssen nur abstract
Eigenschaften im Prototyp erstellen .