Это не то, как вы устанавливаете наследование:
function FML_Text(id){
this.prototype= new FML_Field(id);
// ...
}
Все, что делает, - это создает для экземпляра свойство с именем prototype
.
Это сделано так:
function FML_Text(id){
// ...
}
FML_Text.prototype = new FML_Field();
... и вы не можете передать в него аргумент id
, потому что это происходит до вызова конструктора дочернего объекта. Вместо этого обычно нужно определить функцию «инициализатора», которую каждый уровень в вашей иерархии поддерживает пост-конструкцию, и вызвать ее.
В любом случае это основа, но для действительно надежного наследования требуется больше работы. Например, на самом деле выполнение вызова родительской версии функции, которую также определил дочерний элемент (например, общий инициализатор или каждый раз, когда дочерний объект специализирует родительский метод), на самом деле является немного скрипкой в JavaScript, и есть некоторые другие "ошибки" также. Но, немного поработав, вы можете получить очень эффективные цепочки наследования (включая передачу аргументов времени конструирования родительским инициализаторам).
Вместо того, чтобы летать в одиночку, вы можете использовать одну из существующих реализаций этого материала. Я описал мою в этой статье , которая содержит действительно эффективных обращений к родительским методам ("supercalls"). Библиотека Prototype также обеспечивает эффективную "классовую" систему, хотя именно проблемы с производительностью (и совместимостью) этой системы привели меня к написанию статьи выше. Дин Эдвардс также много писал на эту тему, и Джон Резиг начал свою работу. У меня были проблемы с обоими из них, когда я смотрел на них пару лет назад, но, возможно, были обновления.
Что искать (на мой взгляд):
- Простой, декларативный синтаксис.
- Синтаксис, который очень удобен для вашего класса, имеет закрытые статические члены для реализации, которые не должны быть открытыми (Частные экземпляры методы могут быть выполнены практически в любой системе, но они дорогостоящие; см. обсуждение Крокфорда из них и мое сравнение различных способов достичь их.)
- Система не должна полагаться на декомпиляцию функций (используя метод
toString
в Function
экземплярах). Как у прототипа, так и у Ресига, Я не знаю, как у Эдвардса ', как у Эдвардса'. Декомпиляция функций никогда не была стандартизирована и не работает в некоторых мобильных браузерах. (В версиях Ресига и Эдвардса вызов toString
неявный, и поэтому его немного сложно найти, но он есть: они передают экземпляр функции в тест регулярного выражения, который неявно вызывает toString
функции.)
- Система должна , а не создавать новые функциональные объекты на лету, когда выполняются вызовы методов экземпляра, только когда определены классы (если тогда). Прототип делает, каждый раз, когда вы вызываете метод экземпляра, которому может потребоваться вызвать версию его родителя (их магический аргумент
$super
). Их механизм упрощает использование родительской версии, но за счет (опять же) создания новой функции при каждом вызове независимо от того, действительно ли вы вызываете $super
или нет.