Backbone: Why assign `$('#footer')` to `el`? [duplicate]

Solution 1:

What is the difference between $el and el?

The el view property

this.el can be resolved from a DOM selector string or an Element; otherwise it will be created from the view's tagName, className, id and attributes properties. If none are set, this.el is an empty div, which is often just fine.

It is a DOM element object reference. Do not set el directly, use the view.setElement method instead if you want to change it.

The $el property

A cached jQuery object for the view's element. A handy reference instead of re-wrapping the DOM element all the time.

I like how user mu is too short puts it:

this.$el = $(this.el);

Also do not set $el directly, use the view.setElement method.

The el option

An el reference may also be passed in to the view's constructor.

new Backbone.View({ el: '#element' });
new Backbone.View({ el: $('#element') }); // unecessary

It overrides the el property, which is then used for the $el property.

If a selector string is passed, it is replaced with the DOM element it represents.

Why assign $('#footer') to el?

this.el can be a jQuery object. You can see that Backbone make sure el is a DOM element and $el is a jQuery object of it in the _setElement function:

_setElement: function(el) {
  this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
  this.el = this.$el[0];
},

This shows why this.$el is equivalent to $(this.el).

But what is Backbone.$?

Backbone keeps a reference to whatever is $.

For Backbone’s purposes, jQuery, Zepto, Ender, or My Library (kidding) owns the $ variable.

In our case, $ is jQuery, so Backbone.$ is just jQuery, but Backbone dependencies are flexible:

Backbone's only hard dependency is Underscore.js ( >= 1.8.3). For RESTful persistence and DOM manipulation with Backbone.View, include jQuery ( >= 1.11.0), and json2.js for older Internet Explorer support. (Mimics of the Underscore and jQuery APIs, such as Lodash and Zepto, will also tend to work, with varying degrees of compatibility.)

this.$(selector) is equivalent to $(view.el).find(selector)

In fact, it's a little more efficient, the $ view function is just:

$: function(selector) {
  return this.$el.find(selector);
},

What is a cached jQuery object?

In this case, it only means that a jQuery object is kept inside a variable, which is reused inside the view. It avoids the costly operation of finding the element with $(selector) each time.

You can (and should) use this little optimization whenever possible, like inside the render function:

render: function() {
    this.$el.html(this.template(/* ...snip... */));
    // this is caching a jQuery object
    this.$myCachedObject = this.$('.selector');
},

onExampleEvent: function(e) {
    // avoids $('.selector') here and on any sub-sequent example events.
    this.$myCachedObject.toggleClass('example');
}

Prefixing the jQuery cached object variable with $ is just a standard, not a requirement.


Backbone's source code is less than 2000 lines, it's well-documented and easy to read. I highly encourage everyone to dive into it to easily understand the underlying logic.

They also offer an annotated source page which is even easier to read.

Additional reading

  • Start here: Backbone documentation
  • Introduction to Backbone
  • Backbone patterns
  • Best practices with Backbone