Search code examples
javascriptbackbone.js

Why does backbone use the _.extend() method throughout?


I am curious in creating an MVC javascript framework for fun, and as a learning experience.

Inside backbone.js https://github.com/jashkenas/backbone/blob/master/backbone.js the author uses underscore's _.extend() method to "extend" the backbone object.

Starting with the Model I am trying to figure out the benefit of this.

// Attach all inheritable methods to the Model prototype.
_.extend(Model.prototype, Events, {});

How does this work? Model is already defined before this, then the author wants to Copy all of the properties in the source objects over to the destination object http://underscorejs.org/#extend, he creates a whole bunch of methods inside to interact with the source model as a prototype?

Why not do

Backbone.Model.prototype.get = function() {
    return 'Do Get';
}

Backbone.Model.prototype.set = function() {
    return 'Do Set';
}

Or better yet use Es6? Is the below even the same as the above??

class Model extends Backbone {
  get() {
    return 'Do Get';
  }
  set() {
    return 'Do Set';
  }
}

Am I on the right path, or am I missing something here? Obviously he created this before es6 was a thing, but I am also curious to know if it could have been done.

My angle is do grasp his intentions and recreate the concept without an underscore dependancy.


Solution

  • _.extend is a classical method for safe merging of objects.

    By safe I mean that the first argument of _.extend(obj1, obj2, ..., objN) will get all enumerable properties of all objects, passed as arguments after it.

    _.extend(Backbone.Model.prototype, {
      get: function() {
        return 'Do Get';
      }
    }
    
    // Is an equivalent of
    Backbone.Model.prototype.get = function() {
        return 'Do Get';
    }
    

    Backbone.Events

    Events is a module that can be mixed in to any object, giving the object the ability to bind and trigger custom named events.

    In other words, this object is a set of methods for custom event handling. The reason why Backbone.Model.prototype is extended is explained in the following answer JS - Why use Prototype?

    Talking of ES6, you have to remember, that class keyword only introduces a syntax sugar around old prototype inheritance for constructor functions.

    // This will won't work, since you can't extend objects. It has to be a constructor.
    class Model extends Backbone {
      ...
    }
    

    I will push it a bit further and say taht Backbone doesn't work that well with ES6 classes, see more in Why Backbone.js and ES6 Classes Don't Mix.