// использование существующего или создание нового массива внутреннего использования для событий
var events = this._events[name] || (this._events[name] = []); // в роли this - объект Events
// или объект созданный конструктором, на котором было сделано так _.extend(Model.prototype, Events);
// функция создается, принимает глобальный объект и только что созданную анонимную функцию
(function(root, factory) {}(this, function(root, Backbone, _, $) {})) // и сразу выполняется
// функция, которая
once: function(name, callback, context) {
var self = this; // сохраняет объект, на котором вызвана
var once = _.once(function() {
self.off(name, once); // чтобы знать, с какого объекта себя автоматически удалить при первом вызове
callback.apply(this, arguments);
});
once._callback = callback; // ссылка на колбэк навешивается еще и на функцию обертку, чтобы можно было найти и выключить событие зная колбэк
return this.on(name, once, context); // функция-обертка назначается колбэком на событие
},
trigger: function(name) {
var args = slice.call(arguments, 1); // сохраняем аргументы без имени
if (events) triggerEvents(events, args); // колбэкам, которые закреплены за своим именем, имя не передается
if (allEvents) triggerEvents(allEvents, arguments); // колбэкам, которые вызываются при любом имени, передается комплект аргументов вместе с именем
return this;
}
// а тут пришлось малость пожертвовать красотой кода ради скорости
var triggerEvents = function(events, args) {
var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
switch (args.length) {
case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; // внутри колбэка this будет ev.ctx
case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
// самый медленный вариант, аргсы высыпятся из массива так: ev.ctx.callback(args[0], args[1], args[2] и т.д.)
default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
}
};
// функция, которая вызовется на новеньком объекте ,созданном конструктором из прототипа, вместе с аргументами конструктора
this.initialize.apply(this, arguments);
has: function(attr) { // одна функция объекта
return this.get(attr) != null; // вызывает другую функцию этого же объекта
}
// проверка, выполнение своей функции объектом, выбор и возврат значения
if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
fetch: function(options) {
options = options ? _.clone(options) : {}; // свои новая копия опций в этом пространстве имен
if (options.parse === void 0) options.parse = true; // если нет парса - добавить и включить
var model = this; // сохраняем объект в переменную, чтобы ссылка не менялась
var success = options.success; // сохраняем старую функцию
options.success = function(resp) { // подменяем новой, которая уедет в далекие дали для асинхронного общения, но будет видеть то, что посохраняли
if (!model.set(model.parse(resp, options), options)) return false;
if (success) success(model, resp, options); // вызов старой, если та была
model.trigger('sync', model, resp, options);
};
wrapError(this, options); // error из опций будет знать, с какой моделью работает
return this.sync('read', this, options); // отправка функции в далекие дали для общения с по аяксу
},
// клонирование модели
return new this.constructor(this.attributes);
// массовое добавление методов
var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
_.each(modelMethods, function(method) {
Model.prototype[method] = function() { // в прототип конструктора модели
var args = slice.call(arguments); // которые передадут свои аргументы
args.unshift(this.attributes); // c внутренним объектом модели воглаве
return _[method].apply(_, args); // для обработки соответствующим методам Underscore
};
});
attrs instanceof Model // сконструирован ли объект данным конструктором
// выбор и сразу вызов необходимой функции
this[first ? 'find' : 'filter'](function(model) {
for (var key in attrs) {
if (attrs[key] !== model.get(key)) return false;
}
return true;
});
this.models.sort(_.bind(this.comparator, this)/*вернет функцию обертку, внутри которой всегда будет делаться типа так comparator.call(this)*/);
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий