Что такое Mohawk?
Mohawk (Мохавк или Могавк) — это JS-фреймворк, созданный для Ирокез CMS, и в нем же используемый. Первоначально фреймворк создавался как набор js-функций для создания кроссбраузерных скриптов, однако, впоследствии перерос в самостоятельный фреймворк.
Почему не jQuery или любой другой популярный фреймворк?
Дело в том, что когда создавался Ирокез, jQuery еще не было. В то время был очень популярен Prototype, а jQuery только набирал обороты. Но Prototype был больше популярен в RoR сообществе, поэтому я его не особо хотел использовать :)
Что умеет Мохавк?
На сегодняшний Мохавк — это полноценный кроссбраузерный js-фреймворк, который имеет следующие возможности:
— Создание объектов (объектная модель)
— Работа с DOM (переход по дереву, управление CSS классами и событиями, упрощение работы с DOM)
— Ajax интерфейс (включая упрощенную работу с формами)
— Перетаскивание и изменение размеров объектов
— Небольшой набор визуальных эффектов
— Шаблонизатор (js templates)
— UI компоненты (WYSIWYG, списки, табы, поля ввода и т.д.)
В этой статье, я хотел бы начать с описания объектной модели.
Объектная модель
Основной задачей объектной модели в Мохавке было наличие механизма наследование классов. При создании фреймворка в то время в основном были две популярные реализации ООП в js:
— определение класса как функцию, и последующее наследование через расширение прототипа функции (примерно, как то вот так: www.kevlindev.com/tutorials/javascript/inheritance)
— метод из фреймворка base2 от Dean Edwards (http://code.google.com/p/base2/)
Первый метод не устраивал, т.к. при наследовании от наследуемного класса там начиналась просто беда с ссылками на родителя. Метод от Dean Edwards работал идеально, однако две вещи не давали покоя: 1. «klass» в качестве базового класса и 2. не было возможности ссылаться на родителя, а только на перезаписанный метод родителя. Впрочем, я несколько раз пытался изменить код под свои нужды, но там при разборе метода наследования мозги вскипали :) Если не ошибаюсь, то MooTools до сих пор использует этот метод в своем коде.
Итак, как же работает объектная модель в Мохавке.
Создание класса
Класс создается через функцию Class, единственным аргументом которой будет объект (тело) нашего класса:
var A = new Class({/*описание объекта*/});
* This source code was highlighted with Source Code Highlighter.
Создадим класс Person со свойством name, конструктором принимающим имя и методом hello:
var Person = new Class({
// можно задать значение по умолчанию
name: 'anonoymous',
// конструктор
__construct: function (name) {
self.name = name; // присваиваем свойству объекта переменную
},
// метод
hello: function () {
Console.log('Hello, my name is ' + self.name);
}
});
* This source code was highlighted with Source Code Highlighter.
Как можно увидеть из кода, конструктор задается через поле __construct переданного объекта (очевидно, на название повлиял PHP). Еще одно замечание: внутри методов класса ссылкой на класс является переменная self заместо обычного this. Причина тому в том, что this часто зависит от окружения, а переменная self будет постоянна. В методе hello я пишу сообщение в консоль Мохавка, чтобы в примере вы могли видеть, как оно работает. Как видно, в методе обращение к свойству name происходит через переменную self.
Посмотреть в действии можно здесь: demo.irokez.org/mohawk
А скачать фреймворк с примером тут: irokez.org/download/mohawk
Протестируем наш объект:
var alice = new Person('Alice');
alice.hello();
* This source code was highlighted with Source Code Highlighter.
В консоли увидим: «Hello, my name is Alice».
Наследование
Теперь создадим класс, производный от Person. Пусть это будет Student с дополнительным полем school, новым методом enters и перегруженным методом hello. Наследование выполняется через метод extends у созданного класса Person. Параметром также как и в Class передается «тело» наследуемого класса:
var Student = Person.extend({
school: '',
enters: function (school) {
self.school = school;
},
// перегруженный метод
hello: function () {
// вызов родительского "перегружаемого" метода
parent.hello();
if (self.school) {
Console.log('I study at ' + self.school);
} else {
Console.log('I don\'t study yet');
}
}
});
* This source code was highlighted with Source Code Highlighter.
Как видно из этого примера, ссылку к родителю можно получить через переменную parent.
Тестируем новый класс:
var bob = new Student('Bob');
bob.enters('MIT');
bob.hello();
* This source code was highlighted with Source Code Highlighter.
Вывод консоли:
Hello, my name is Bob
I study at MIT
Статические свойства и методы
В недавней версии в Мохавк были добавлены статические свойства и методы. Доступ к ним осуществляется через переменную static. Посмотрим пример:
var Phd = Student.extend({
hi: function () {
self.hello();
Console.log('My degree is ' + static.degree);
}
})
Phd.degree = 'PhD'; // статическое свойство (можно использовать как константу класса) degree
// создадим объект
var carol = new Phd('Carol');
carol.enters('MIT');
carol.hi();
* This source code was highlighted with Source Code Highlighter.
Консоль выдаст:
Hello, my name is Carol
I study at MIT
My degree is PhD
Синглтон
Иногда класс требуется только в одном экземпляре, для этого можно воспользоваться готовой функцией Singletone:
var ProfSmith = new Singletone({
hello: function () {
Console.log('Hello, I am Prof. Smith');
}
});
ProfSmith.hello(); // Hello, I am Prof. Smith
* This source code was highlighted with Source Code Highlighter.
Как видно из примера, объект ProfSmith создается сразу же при его определении.
Синтаксический сахар
Ну и напоследок небольшой синтаксический сахар. Угадайте, что выдаст в консоль следующий код:
var sugar = new Singletone({
a: function () {
Console.log('I am called from method ' + __function__);
},
b: function () {
Console.log('I am called from method ' + __function__);
}
});
sugar.a();
sugar.b();
* This source code was highlighted with Source Code Highlighter.
В следующей статье постараюсь продолжить описание фреймворка, если будет вам интересно. Всем спасибо за внимание.
PS: если вы скачали фреймворк и используете ИЕ7, у Мохавка могут возникнуть некоторые разногласия с ИЕ7. Поэтому если есть возможность, запустите его через локальный веб-сервер, чтобы адрес был хотя бы localhost.