|
Разбираем AjaxOOP
Всем доброго времени суток.
Пересмотрев кучу библиотек для организации OOP на JavaScript более всего мне понравился синтаксис реализованный в библиотеке Ajax.OOP. Беда в том, что 1. Проект закрыт судя по всему 2. Файл содержит еще кучу всякой лабуду для Ajax, которая и даром не нужна. Посему решил понадергать кода оттуда что бы иметь маленькую библиотечку для OOP. Поскольку не считаю себя супер профессионалом в JS то прошу помощи у сообщества в сем деле. Предлагаю разбирать построчно анализировать код. Вообщем основная функция которая создает класс это Ajax.Class Предлагаю просто назвать ее _class код выкладываю далее ... |
чуть не забыл, понадобятся еще служебные функции.
в исходнике реализована функция $a которая используется по всей библиотеке. Нам интересна ее способность преобразовывать аргументы функции в массив. записал так
function args2array(obj)
{
var al = obj.length;
var args = new Array(al);
while (al--)
args[al] = obj[al];
return args;
};
Еще есть функции проверяющие тип объекта. Реализация их не очень интересна, однако для чистоты эксперимента выкладываю код тоже Интерес вызывает isElement и isRegExp так как похоже для корректной работы потребуются дополнительные действия, но об этом позже.
function isElement(obj)
{
return (obj && obj.nodeType && obj.nodeType == 1) ? true : false;
};
function isRegExp(obj)
{
return (obj && obj.constructor === RegExp);
};
function isString(obj)
{
return (typeof obj == 'string');
};
function isNumber(obj)
{
return (typeof obj == 'number');
};
function isBoolean(obj)
{
return (typeof obj == 'boolean');
};
function isNull(obj)
{
return (obj === null);
};
function isUndefined(obj)
{
return (obj === 'undefined' || obj === undefined || obj === 'unknown');
};
function isArray(obj)
{
return (obj && obj.constructor === Array);
};
function isSimple(obj)
{
return (isString(obj) || isNumber(obj) || isBoolean(obj) || isRegExp( obj));
};
function isFunction(obj)
{
return (obj && obj.constructor === Function);
};
function isObject(obj)
{
return (obj && !(isArray( obj) || isFunction( obj) || isSimple( obj)));
};
|
Для проверки на регэксп должно хватить
alert( /inline regexp/ instanceof RegExp );
alert( new RegExp('regexp') instanceof RegExp );
alert( '/not regexp+?/' instanceof RegExp );
|
И далее сама функция _class
//получаем массив аргументов
var args = args2array(arguments);
var al = args.length;
// Если есть хотя бы 2 аргумента, значит первый это предок, запоминаем его и убираем из массива. Если предка нет, то он NULL
var parent = (al > 1 ? args.shift() : null);
// Получаем и запоминаем описание самого класса. Если такового нет, то пустое тело. Как и с предком убираем из массива аргументов тело класса.
var declaration = (args.shift() || {});
// Типа конструктор ;-)
var constructor = 'constructor';
// Проверяем правильный ли тип предка
if (parent && !isFunction(parent))
{
throw new TypeError( 'in class definition - first argument is not a parent class constructor!');
}
// Проверяем является ли тело класса таковым
if (declaration && (!isObject(declaration) ||
declaration == window ||
declaration == document.body ||
declaration == document ||
isElement(declaration)))
{
throw new TypeError( 'in class definition - ' + (args.length > 1 ? 'second' : 'passed') + ' argument is not a class declaration object!');
}
// Собственно это и есть наш класс
var _class = function()
{
this[constructor].apply(this, args2array(arguments));
}
И тут начались проблемы с пониманием. apply - вызов функции с массивом параметров У свойства текущего контекста this[constructor] (фактически this['constructor']) вызывается (он сам по идее и вызывается) с передачей текущего контекста и оставшимися параметрами. Что зачем почему не понятно.
// Пошло наследование свойств через прототип
if (parent)
{
var _parent = Function.blank;
_parent.prototype = parent.prototype;
_class.prototype = new _parent;
}
1. Содается переменная функция временая _parent ей присваивается пустая функция (она определена в другом месте как пустая) 2. Prototype этой временной функции присваивается prototype предка. 3. Prototype нового создаваемого класса становться вновь созданный экзампляр временной функции (которая имеет тот же prototype что и предок)
// коли определены в текущем классе свойства, так соотвственно присвоить их, а коли они были в предке то переопределить.
// ну хак с конструктором для IE
if (declaration)
{
for (var property in declaration)
{
_class.prototype[property] = declaration[property];
}
// line below is to fix bug with constructors in IE
_class.prototype[constructor] = declaration[constructor] || Function.blank;
}
// этот кусок меня если четно не понятен. Особенно момент с возвратом прототипа пустой функции. Если честно не совсем понятно зачем создавать эти указатели на конструкторы ....
_class.prototype.$super = parent ? parent.prototype : Function.blank.prototype;
_class.prototype.$_super = parent ? parent : Function.blank;
_class.prototype.$_self = _class;
// собственно вернуть готовый класс
return _class;
Проанализировав код вдоль и поперек , не могу понять где тело конструктора мы присваиваем в _class Судя по всему в теле должны быть только свойства и методы определены, а код не допускается. ;-) Сложно выразился ... т.е. в теле любой код должен быть присвоением свойства или метода в синтаксисе someProp: 10, someMethod: function() {}, |
Цитата:
|
Может теорию сначала почитаете?
|
Цитата:
Цитата:
Если же все же это мне, то отвечу, читал я теорию и на этом сайте и на других, много и вдумчиво. Но поскольку нет идеологии или если хотите парадигмы ООП на JavaScript то вариантов много получается и почти все они построены на "хаках". |
Цитата:
|
eai, прежде чем что-то утверждать прочтите это.
Смею вас уверить, что ваша коробка транзисторов, резисторов, дросселей и емкостей полностью построена на, как вы выразились, "хаках". Для примера: многопоточность и многоядерность. Везде применяются те или иные методы обхода проблемных мест. |
Уф, я так и знал, что у меня будут сложности с пониманием в этом форуме. Ибо все же язык (общения) программиста на С++ всегда отличается людей которые работают на скриптовых языках. :)
Владлен, я не утверждал что нельзя использовать ООП на JS. Как вы можете заметить, я скорее наоборот всеми силами за. Однако как я заметил и заметили другие члены сообщества в разных местах в интернете, нет , как бы это яснее выразиться ..., нативной что ли возможности использовать это. Цитата:
Предлагаю не спорить по этому вопросу, так как вопроса в сущности то нет. |
| Часовой пояс GMT +3, время: 00:07. |
|