I want to built a Backbone.Model like object/class.
I looked through the Backbone docs and found that they create a inheritable object/class with its inheritable attributes, methods in two steps:
I. Create a function with some attributes
var Model = Backbone.Model = function(attributes, options) {
var defaults;
attributes || (attributes = {}); //?
if (options && options.parse) attributes = this.parse(attributes); //?
if (defaults = getValue(this, 'defaults')) {
attributes = _.extend({}, defaults, attributes); // ?
}
if (options && options.collection) this.collection = options.collection;
this.attributes = {};
this._escapedAttributes = {};
this.cid = _.uniqueId('c');
this.changed = {};
this._silent = {};
this._pending = {};
this.set(attributes, {silent: true});
this.changed = {};
this._silent = {};
this._pending = {};
this._previousAttributes = _.clone(this.attributes);
this.initialize.apply(this, arguments);
};
II. use underscore’s extend to give it some functions
_.extend(Model.prototype, Events, { // Events?
changed: null,
_silent: null,
_pending: null,
idAttribute: 'id',
initialize: function(){},
toJSON: function(options) {
return _.clone(this.attributes);
}
// other Model methods...
};
I have some questions about this behaviour:
- What does line 3-4 in the first part do
- What happens in line 6?
- Why do we overgive “_.extend” the Events object, what else could I give as parameter?
Is there anything else I have to pay attention about?
Regards
Line 3,
attributes || (attributes = {});is an example of short circuit evaluation.If attributes has a falsy valye, then javascript will evaluate the second part of the OR expression. That part assigns
attributesa value of{}, an empty object. The end result is, if attributes is null or undefined (typical case) then, assign attributes an empty object.That line is equivalent to saying:
Same case with line 4,
if (options && options.parse) attributes = this.parse(attributes);If an
optionsobject exists, ie its not null or undefined, and theoptionsobject has a valid property calledparse, then assign attributes the value ofthis.parse(attributes);EDIT 1:
The
_.extendlines can be explained by the Underscore.js documentation.Its a standard pattern to create a new object that will contain properties of all passed in objects. In the first example
attributes = _.extend({}, defaults, attributes); // ?the pattern is used to override the default values with what ever may have been passed. You would see this pattern followed in most plugins that allow you to pass in an options object. If you dont pass in anything, the default values will be used. If you pass in only a few properties, the remaining will get their values from the defaults.http://api.jquery.com/jQuery.extend/ is NOT the exact same thing. But its very similar. Their documentation is much better. You will understand the concept better.
EDIT 2:
The Backbone Events class has some event handling related methods. The Backbone Model class also needs to be able to make use of event handling. It needs to raise events to tell the view to re-render itself, it needs to listen to events from the dom when the view changes the underlying data. This event handling functionality could either have been re-written from scratch when defining the Model class, or the Model class could be extended to get these methods from the Events class. That latter is what is happening.
If you read the documentation for the $.extend or _.extend, you will realize that the Model class is being extended not just with the properties under Events, but also with other properties like toJSON and initialize etc…