Backbone.js object inheritance

If you’ve ever wondered if the basic classes in Backbone.js could be inherited by other, related objects, the answer is a resounding “Yes!” The very same extend method used to create models, views, and collections is just as useful for passing methods from any of those objects on to its children. That’s good news, because it makes it ridiculously easy to share code between similar pieces of a Backbone application.

An example’s worth at least a thousand words, so here’s a simple one: if animal is the base object and cat is the child, extend (predictably) will give the cat a voice.

  var animal = Backbone.Model.extend({
    sound: function() { 
      return '(incoherent grunting)'; 
    },
    talk: function() { 
      alert(this.sound()); 
    }
  });

  var cat = animal.extend({
    sound: function() {
      return 'meow';
    }
  });

  (new cat).talk(); // meow

Instead of grunting incoherently, the new cat simply meows through the talk() method defined for all animals.

The super function

Children begin by loving their parents; as they grow older they judge them; sometimes, they forgive them

(Oscar Wilde)

Even the most judgmental of children may occasionally need to parent methods. Fortunately, Backbone’s designers included the __super__ property to grant access to the methods in the parent object. Using it can be a bit unwieldy, but Josh Nielsen provides a very neat helper extension for Backbone.Model:

Backbone.Model.prototype._super = function(funcName){
  return this.constructor.__super__[funcName].apply(this, _.rest(arguments));
}

By using ._super, children gain access to both their parents’ methods and their own:

var jabberwock = animal.extend({
  sound: function() { return '(whiffle, burble)' },
  talk: function() {
    alert(this.sound() + ',' + this._super('sound'));
  }
});

(new jabberwock).talk(); // (whiffle, burble), (incoherent grunting)

A word of caution: there’s at least one closure “gotcha” to beware of hiding out here. Parent methods called using _super remain bound to the child class. That means that the value of this will still be the child class when a parent method is called. This can be a bit counterintuitive. Instead of hearing incoherent grunting when a jabberwock talks through _super, a quick demonstration breeds a different result:

(new jabberwock)._super('talk'); // (whiffle, burble)

Used appropriately, Backbone’s extend method can save volumes of redundant code. It’s predictable, efficient, and just waiting to be taken advantage of. Don’t let it down!

Oh, and you can play with an example here

Featured