70

I need to call the initialize method of the parent class, from inside the inherited MyModel-class, instead of completely overwriting it as I am doing today.

How could I do this?

Here's what my code looks right now:

BaseModel = Backbone.Model.extend({
    initialize: function(attributes, options) {
        // Do parent stuff stuff
    }
});

MyModel = BaseModel.extend({
    initialize: function() {
        // Invoke BaseModel.initialize();
        // Continue doing specific stuff for this child-class.
    },
});
wheresrhys
  • 22,558
  • 19
  • 94
  • 162
Industrial
  • 41,400
  • 69
  • 194
  • 289

8 Answers8

129

Try

MyModel = BaseModel.extend({
    initialize: function() {
        BaseModel.prototype.initialize.apply(this, arguments);
        // Continue doing specific stuff for this child-class.
    },
});
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
52
MyModel = BaseModel.extend({
    initialize: function() {
        MyModel.__super__.initialize.apply(this, arguments);
        // Continue doing specific stuff for this child-class.
    },
});
Raynos
  • 166,823
  • 56
  • 351
  • 396
  • 1
    @Industrial then it's doing something silly. Try `this.__super__.initialize.apply(this, arguments);` – Raynos Jan 23 '12 at 13:29
  • 5
    `__ super __` is not intended to use it directly, as the underscored name implies. – Yury Tarabanko Jan 23 '12 at 13:49
  • @YuryTarabanko sure it is, it's just someone choose a `__super__` naming convention in their `inherits` utility function to avoid naming conflicts. It's exposed by backbone – Raynos Jan 23 '12 at 14:33
  • 5
    @Raynos: Why not `BaseModel.prototype.initialize.apply(this, arguments);`? this should work without `__super__`. – Yury Tarabanko Jan 23 '12 at 14:43
  • 1
    @YuryTarabanko either works. The `__super__` solution is more elegant because it doesn't require changing when you rename `BaseModel`. – Raynos Jan 23 '12 at 14:50
  • 6
    http://documentcloud.github.com/backbone/#Model-extend Brief aside on super: JavaScript does not provide a simple way to call super — the function of the same name defined higher on the prototype chain. If you override a core function like set, or save, and you want to invoke the parent object's implementation, you'll have to explicitly call it... – Yury Tarabanko Jan 23 '12 at 15:09
  • 1
    In Ember.js <3 you just do `this._super()`. tada! it's magic. :) – Samuel Katz Jun 03 '12 at 14:34
  • @SalmanPK I'm sure that will break horribly in plenty of edgecases. It's impossible to implement a sensibly semantic `super` in JS. – Raynos Jun 03 '12 at 15:05
  • 4
    FWIW Jeremy Ashkenas [**states**](https://github.com/jashkenas/backbone/pull/787#issuecomment-3143358) that `__super__` is not intended to be used directly. – MikeSchinkel Jul 26 '13 at 18:01
11

This worked for me, when I was trying to inherit among my models:

MyModel.prototype.initialize.call(this, options);

Referenced from http://documentcloud.github.com/backbone/#Model-extend

Thanks.

rookieRailer
  • 2,313
  • 2
  • 28
  • 48
5

I think it'd be

MyModel = BaseModel.extend({
    initialize: function() {
        this.constructor.__super__.initialize.call(this);
        // Continue doing specific stuff for this child-class.
    },
});
wheresrhys
  • 22,558
  • 19
  • 94
  • 162
  • It's `this.__super__.initialize.call(this);` – Raynos Jan 23 '12 at 11:39
  • Both `this.__super__.prototype.initialize.call(this);` and `this.__super__.initialize.call(this);` throws `this.__super__ is undefined` in Firebug. – Industrial Jan 23 '12 at 13:07
  • Try this.constructor.__super__.initialize.call(this); – wheresrhys Jan 23 '12 at 14:06
  • 2
    I wanted to pass arguments to the initialize function, and this is the only version that worked for me this.constructor.__super__.initialize.call(this,arguments); – Khalid Dabjan Jul 06 '13 at 12:42
  • FWIW Jeremy Ashkenas [**states**](https://github.com/jashkenas/backbone/pull/787#issuecomment-3143358) that `__super__` is not intended to be used directly. – MikeSchinkel Jul 26 '13 at 18:02
4

this seems to be almost a duplicate of Super in Backbone, so you want something like this:

Backbone.Model.prototype.initialize.call(this);
Community
  • 1
  • 1
ErichBSchulz
  • 15,047
  • 5
  • 57
  • 61
2

Similar to @wheresrhys, but I would use apply instead of call in case BaseModel.initialize is expecting arguments. I try to avoid processing the attributes map that can be passed to a Backbone Model upon initialization, but if the BaseModel were actually a View or a Collection then I might want to set options.

var MyModel = BaseModel.extend({
    initialize: function() {
        this.constructor.__super__.initialize.apply(this, arguments);
        // Continue doing specific stuff for this child-class.
    },
});
  • FWIW Jeremy Ashkenas [**states**](https://github.com/jashkenas/backbone/pull/787#issuecomment-3143358) that `__super__` is not intended to be used directly. – MikeSchinkel Jul 26 '13 at 18:02
0

here's a multi generation callSuper method, just add it to your extending class.

callSuper: function (methodName) {
    var previousSuperPrototype, fn, ret;

    if (this.currentSuperPrototype) {
        previousSuperPrototype = this.currentSuperPrototype;
        // Up we go
        this.currentSuperPrototype = this.currentSuperPrototype.constructor.__super__;
    } else {
        // First level, just to to the parent
        this.currentSuperPrototype = this.constructor.__super__;
        previousSuperPrototype = null;
    }

    fn = this.currentSuperPrototype[methodName];

    ret = (arguments.length > 1) ? fn.apply(this, Array.prototype.slice.call(arguments, 1)) : fn.call(this);

    this.currentSuperPrototype = previousSuperPrototype;

    return ret;
}
Bnaya
  • 765
  • 6
  • 15
-4

You might consider rewriting your code using functional inheritance.

var BackBone=function(){
    var that={};

    that.m1=function(){

   };
   return that;

};

var MyModel=function(){

 var that=BackBone();
 var original_m1=that.m1;

//overriding of m1
 that.m1=function(){
    //call original m1
 original_m1();
 //custom code for m1
  };
};
Dani Cricco
  • 8,829
  • 8
  • 31
  • 35
  • i doubt rewriting backbone is in order here :) we got to manage with the structure backbone gives us, and there are far better solutions than rewriting all this, like the __super__ is more than enough. – Sander Jan 23 '12 at 12:04