Питання досить старе, але я створив якесь можливе рішення, як створити абстрактний "клас" і блокувати створення об'єктів цього типу.
//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();
Як ви бачите, останній об'єкт дає нам помилку, це тому, що тварина в прототипі має властивість abstract
. Щоб бути впевненим, що це тварина - це не те, що є Animal.prototype
в прототипі ланцюга:
Object.getPrototypeOf(this).hasOwnProperty("abstract")
Тому я перевіряю, чи є у мого найближчого об'єкта прототипу abstract
властивість, лише об'єкт, створений безпосередньо з Animal
прототипу, матиме цю умову як істинний. Функція hasOwnProperty
перевіряє лише властивості поточного об'єкта, а не його прототипи, тому це дає нам 100% впевненість, що властивість декларується тут не в прототипі ланцюга.
Кожен об'єкт, що походить від Object, успадковує метод hasOwnProperty . Цей метод може бути використаний для визначення, чи має об'єкт вказану властивість як безпосередню властивість цього об'єкта; на відміну від оператора в, цей метод не перевіряє ланцюг прототипу об'єкта. Більше про це:
На мою думку, нам не доведеться змінювати constructor
кожного разу після того, Object.create
як це є в поточній найкращій відповіді від @ Jordão.
Рішення також дозволяє створити багато абстрактних класів в ієрархії, нам потрібно лише створити abstract
властивість в прототипі.