Reputation: 8139
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:
Is there anything else I have to pay attention about?
Regards
Upvotes: 1
Views: 4243
Reputation: 5916
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 attributes
a 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:
if (attributes == false) { // attributes can be any value that evaluates to false
// attributes could be null, undefined, false, 0 etc
attributes = {};
}
Same case with line 4, if (options && options.parse) attributes = this.parse(attributes);
If an options
object exists, ie its not null or undefined, and the options
object has a valid property called parse
, then assign attributes the value of this.parse(attributes)
;
EDIT 1:
The _.extend
lines 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...
Upvotes: 3
Reputation: 16971
As to what's going on on line 6 - the object is created that contains all properties of defaults
object and all from attributes
object.
Any property of defaults
object that is already defined in attributes
object will get overwriten by the value of latter.
Upvotes: 1