A questão é bastante antiga, mas criei alguma solução possível como criar "classe" abstrata e bloquear a criação de objeto desse 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 você pode ver, o último objeto nos dá erro, é porque Animal no protótipo tem propriedade abstract
. Para ter certeza de que é Animal, não algo que tenha Animal.prototype
na cadeia de protótipo que eu faço:
Object.getPrototypeOf(this).hasOwnProperty("abstract")
Então, eu verifico se meu objeto de protótipo mais próximo tem abstract
propriedade, apenas o objeto criado diretamente do Animal
protótipo terá essa condição como verdadeira. A função hasOwnProperty
verifica apenas as propriedades do objeto atual, não seus protótipos, então isso nos dá 100% de certeza de que a propriedade é declarada aqui e não na cadeia de protótipos.
Cada objeto descendente de Object herda o método hasOwnProperty . Este método pode ser usado para determinar se um objeto tem a propriedade especificada como uma propriedade direta desse objeto; ao contrário do operador in, este método não verifica a cadeia de protótipo do objeto. Mais sobre isso:
Na minha proposição não temos que mudar constructor
todas as vezes depois Object.create
como está na melhor resposta atual do @Jordão.
A solução também permite criar muitas classes abstratas na hierarquia, precisamos apenas criar abstract
propriedades no protótipo.