• Blogs (9)
    • πŸ“± 236 - 992 - 3846

      πŸ“§ jxjwilliam@gmail.com

    • Version: β€πŸš€ 1.1.0
  • Backbone.js, Spine.js extend and inheritance

    Blogs20142014-11-08


    Backbone.js, Spine.js extend and inheritance

    Backbone use extend() to set up the prototype chain, e.g.:

    • Backbone.Model.extend(instanceProperties, [classProperties]);
    • Backbone.View.extend(instanceProperties, [classProperties]);

    Spine.js use include() and extend() to the same thing. e.g.:

    • var User = Spine.Class.create();
    • User.include(instanceProperties)
    • User.extend(classProperties)
    • var Book = Spine.Class.create(instanceProperties, [classProperties]);

    Here I list the implementation of 2 of them, for comparison and reference.

    Backbone.js extend function
      var extend = function(protoProps, staticProps) {
        var parent = this;
        var child;
    
        // The constructor function for the new subclass is either defined by you
        // (the "constructor" property in your `extend` definition), or defaulted
        // by us to simply call the parent's constructor.
        if (protoProps && _.has(protoProps, 'constructor')) {
          child = protoProps.constructor;
        } else {
          child = function(){ return parent.apply(this, arguments); };
        }
    
        // Add static properties to the constructor function, if supplied.
        _.extend(child, parent, staticProps);
    
        // Set the prototype chain to inherit from `parent`, without calling
        // `parent`'s constructor function.
        var Surrogate = function(){ this.constructor = child; };
        Surrogate.prototype = parent.prototype;
        child.prototype = new Surrogate;
    
        // Add prototype properties (instance properties) to the subclass,
        // if supplied.
        if (protoProps) _.extend(child.prototype, protoProps);
    
        // Set a convenience property in case the parent's prototype is needed
        // later.
        child.__super__ = parent.prototype;
    
        return child;
      };
    Spine.js include and extend function
    var moduleKeywords = ["included", "extended"];
    var Class = Spine.Class = {
        inherited: function(){},
        created: function(){},
    
        prototype: {
          initialize: function(){},
          init: function(){}
        },
    
        create: function(include, extend){
          var object = Object.create(this);
          object.parent    = this;
          object.prototype = object.fn = Object.create(this.prototype);
    
          if (include) object.include(include);
          if (extend)  object.extend(extend);
    
          object.created();
          this.inherited(object);
          return object;
        },
    
        init: function(){
          var instance = Object.create(this.prototype);
          instance.parent = this;
    
          instance.initialize.apply(instance, arguments);
          instance.init.apply(instance, arguments);
          return instance;
        },
    
        proxy: function(func){
          var thisObject = this;
          return(function(){
            return func.apply(thisObject, arguments);
          });
        },
    
        proxyAll: function(){
          var functions = makeArray(arguments);
          for (var i=0; i < functions.length; i++)
            this[functions[i]] = this.proxy(this[functions[i]]);
        },
    
        include: function(obj){
          for(var key in obj)
            if (moduleKeywords.indexOf(key) === -1)
              this.fn[key] = obj[key];
    
          var included = obj.included;
          if (included) included.apply(this);
          return this;
        },
    
        extend: function(obj){
          for(var key in obj)
            if (moduleKeywords.indexOf(key) === -1)
              this[key] = obj[key];
    
          var extended = obj.extended;
          if (extended) extended.apply(this);
          return this;
        }
      };