Backbone.js accessing model attributes within model – this.attribute VS this.get(‘attribute’)

backbone.jsmodel

From my understanding the attributes of a Backbone.js model are supposed to be declared as somewhat private member variables by saying

this.set({ attributeName: attributeValue })
// accessing the value
this.get('attributeName');

But when I am writing functions whitin the actual model it seems much simpler to say like this:

this.attributeName = attributeValue;
// accessing the value
this.attributeName;

Also I would assume that the latter version would be faster to process since it doesn't go through backbone.js's event management.

So I was wondering how you pros do with attributes that are primarily used internally in the model. These are the attributes that one would actually want to be a bit shielded from the outside so having them exposed like in the latter example maybe isn't right still. When I have been looking at examples for the backbone.js view which doesn't have get and set methods it seems fine to do like in the second example. So is there any nice rule of thumb when to use get/set(attribute) or this.attribute when coding within the model? Or maybe an example of a model that makes this clearer?

Best Answer

When to use model.get(property) and model.set(...)

You should use get and set to access the model's data. This means any attributes that are part of the model's serialized representation that is retrieved using fetch and persisted using save.

When to use model.attributes.property

Never.

You should always use get, and especially set, instead of accessing the model.attributes object directly, although I've seen conflicting opinions about this. I believe there is a contract between a model and it's consumers, which guarantees that the consumer can be notified of any changes to the model's data using the change event. If you modify the internal attributes object directly, events are not sent and this contract is broken. Backbone events are very fast, especially if you don't have any listeners attached to them, and it's not a point that benefits from over-optimization on your part.

Although accessing the attributes directly instead of get is quite harmless on it's own, it should be avoided so the attributes object can be considered totally, completely private.

If you absolutely need to prevent some change triggering events, you can use the silent:true option: model.set({key:val}, {silent:true}). This does break the aforementioned contract, and even Backbone's own documentation gives the following caveat:

Note that this is rarely, perhaps even never, a good idea. Passing through a specific flag in the options for your event callback to look at, and choose to ignore, will usually work out better.

When to use model.property

Any properties which are not data, i.e. temporary state variables, calculated properties etc. can be attached directly to the model entity. These properties should be considered temporary and transitive: they can be recreated upon model initialization or during its lifetime, but they should not be persisted, whether public or private. A typical naming convention is to prefix private properties with the _ character as follows:

this._privateProperty = 'foo';
this.publicProperty = 'bar';
Related Topic