La pregunta es bastante antigua, pero creé una posible solución sobre cómo crear una "clase" abstracta y bloquear la creación de un objeto de ese tipo.
//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();
Como puede ver, el último objeto nos da un error, es porque Animal en el prototipo tiene propiedad abstract
. Para estar seguro de que es Animal, no algo que tenga Animal.prototype
en la cadena de prototipos que hago:
Object.getPrototypeOf(this).hasOwnProperty("abstract")
Así que verifico que mi objeto prototipo más cercano tenga la abstract
propiedad, solo el objeto creado directamente a partir del Animal
prototipo tendrá esta condición en verdadera. La función hasOwnProperty
comprueba solo las propiedades del objeto actual, no sus prototipos, por lo que esto nos da un 100% de seguridad de que la propiedad se declara aquí, no en la cadena de prototipos.
Cada objeto que desciende de Object hereda el método hasOwnProperty . Este método se puede utilizar para determinar si un objeto tiene la propiedad especificada como propiedad directa de ese objeto; a diferencia del operador in, este método no comprueba la cadena del prototipo del objeto. Más sobre esto:
En mi propuesta, no tenemos que cambiar constructor
cada vez después Object.create
como está en la mejor respuesta actual de @ Jordão.
La solución también permite crear muchas clases abstractas en jerarquía, solo necesitamos crear abstract
propiedades en el prototipo.