Как известно, поддержка ООП в JavaScript весьма своезобразная. Настолько своеобразная, что лучше бы такой поддержки там совсем не было (чтоб народ не смущать). К сожалению, когда дело доходит до чего-то более сложного, чем обработка кнопки на веб-страничке - без человеческого ООП трудно. Поэтому народ массово лепит фрэймворки, которые пытаются эмулировать нормальное ООП (добавляя своих проблем, как и положено фрэймворкам).
Так получилось, что в задаче возникла иерархия типов и мне потребовалось проверить принадлженость объекта типу в иерархии. Без привлечения фрэймворков, минимальный вариант на голом JavaScript. В JavaScript для этого (как и положено ООП языку) есть оператор 'instanceof'. Проблема в том, что пользовательских типов как таковых в JavaScript нет, поэтому и "наследуются" не типы, а объекты. Если погуглить по теме, то можно (легко) найти примерно такой вариант:
function A(){} // как бы конструктор класса А
function B(){} // как бы конструктор класса Б
B.prototype = new A(); // B наследует A
var b = new B();
assert(b instanceof A);
Проблемы начинаются, когда "конструкторы" начинаются делать что-то интересное - принимать параметры, вызывать базовые конструкторы, инциализировать поля объекта. Все потому, что смешиваются в одном два понятия: объект типа и тип объекта.
Я делал несколь попыток отделить мух от котлет - наконец заработал вот такой вариант:
function AType(){}
function BType(){}
BType.prototype = new AType(); // BType наследует AType
function A(a){this.fieldA = a;}
A.prototype = new AType(); // A - конструктор типа AType
function B(a, b)
{
A.call(this, a); // вызов базового конструктора
this.fieldB = b;
}
B.prototype = new BType(); // B - конструктор типа AType
var b = new B('a', 'b');
assert(b instanceof AType);
assert(b instanceof BType);
assert(b.fieldA == 'a');
assert(b.fieldB == 'b');
В гугле ничего подобного не видел, поэтому решил написать сюда и обсудить. Может кто предложит более простое/правильное решение.