И далее сама функция _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() {},