Недавно понадобилось для проекта с jQuery реализовать наследование, написал плагин для jQuery, где релизованы идеи, описанные в «Еще раз о наследовании в JavaScript». Плагин находится на code.google — code.google.com/p/jquery-inheritance/
Работает так:
$.inherit([base], methods, [statical])
Пример:
// A — базовый тип
var A = $.inherit(
{
// __constructor — специальный метод, вызываемый при создании экземпляра
__constructor : function(property) {
this.property = property;
},
getProperty : function() {
return this.property + ' of A';
},
getType : function() {
return 'A';
}
},
{
// статическое свойство, доступное изнутри как this.__self.staticMember
staticMember : 'staticA'
});
// B — тип, наследуемый от A
var B = $.inherit(
A,
{
// перекрытие с вызовом одноименного метода базового класса
getProperty : function() {
return this.__base() + ' of B';
},
// просто перекрытие
getType : function() {
return 'B';
}
},
{
staticMember : 'staticB'
});
var instance = new B('value');
console.log(instance.getProperty());
console.log(instance.getType());
console.log(instance.__self.staticMember);
А кто вообще как использует, и использует ли вообще, наследование?
9 комментариев:
Я использую Base, расширенный методами bind, unbind и trigger. Всё собираюсь написать заметку про это.
Одна из идей (про вызов одноименного метода базового класса), реализованных в моем плагине, как раз заимствована из base2 :)
Получается, что у тебя все "классы" имеют bind, unbind, trigger?
Ну да. Bind и unbind являются обёртками для jQuery.event.addWithContext (позволяет передавать контекст обработчика) и jQuery.event.remove, а вот trigger пришлось написать с нуля: в jQuery он делает много лишних телодвижений.
Получается довольно понятный и компактный код как для обычных, так и для jQuery-объектов:
jQuery('#foo').bind('click', this._onFooClick, this);
this._bar.bind('Enable', this._onBarEnable, this);
jQuery('#foo').bind('click', this._onFooClick, this);
Переопределен нативный bind в jQuery?
Ага.
Обожаю Jquery
www.profdesigner.com
Прежде всего спасибо за плагин ;)
Через некоторое я время столкнулся со следующей проблемой:
Когда метод объекта назначается на событие, метод выполняется в контекста объекта в котором сработало событие => в методе никак не добраться до исходного объекта
$('#id').click(instance.method)
Тоже самое и для статических методов.
Обычно, проблема решается так:
$('#id').click(function() { instance.method() })
В добавок мне нужно было сделать unbind события. Хранить где-то новый callback не удобно.
По-этому я решил исправить эту проблему в самом jQuery.inherit:
http://ti-webdev.blogspot.com/2009/10/jquery.html
Буду рад если изменения попадут в google code.
to Ti: У вас на каждое инстанцирование объекта делается не совсем легкая операция replaceMethodContent(this);. Как-то меня это очень смущает.
Спасибо за плагин. Не подскажете, почему вызов базового метода не обернут в try-finally? Это просто оптимизация путем забивания на редко используемые exception-ы или что-то другое?
this.__base = baseMethod;
try {
var result = overrideMethod.apply(this, arguments);
} finally {
this.__base = baseSaved;
}
Отправить комментарий