8

Please check out the following example:

MyBaseClass = function(a) {
     this.a = a;
};

$.extend(MyBaseClass.prototype, {
    init: function() {
        console.log('I am initializing the base class');
    }
});

MyChildClass = $.extend(MyBaseClass, {
    init: function() {
        MyBaseClass.prototype.init();
        console.log('I am initializing the child class');
    }
});

var = new MyChildClass();
var.init();

Тhis should output both 'I am initializing the base class' and 'I am initializing the child class'.

I need to be able to inherit the class MyBaseClass, but still to be able to call his init() method at the beginning of the new init() method.

How do I do that?

7
  • 3
    $.extend doesn't do what you think. Commented Apr 8, 2013 at 9:48
  • 2
    kind of a glaring issue with this code is the use of var at the bottom Commented Apr 8, 2013 at 9:49
  • 3
    What is $.extend anyway? Commented Apr 8, 2013 at 9:51
  • @FelixKling one is defined by jQuery. I'm assuming this one. Commented Apr 8, 2013 at 9:53
  • @JanDvorak I'm sure Felix knew it but was pointing that OP should have added the relevant tag. Commented Apr 8, 2013 at 9:54

3 Answers 3

19

jQuery's extend doesn't build inheritance but "Merge the contents of two or more objects together into the first object".

Use prototype based inheritance to achieve your inheritance and explicitly call the "super" method :

MyBaseClass = function(a) {
     this.a = a;
};
MyBaseClass.prototype.init = function() {
    console.log('I am initializing the base class');
};

MyChildClass = function(a) {
  this.a = a;
}
MyChildClass.prototype = Object.create(MyBaseClass.prototype); // makes MyChildClass "inherit" of MyBaseClass
MyChildClass.prototype.init = function() {
    MyBaseClass.prototype.init.call(this); // calls super init function
    console.log('I am initializing the child class');
};

var child= new MyChildClass();
child.init();

Output :

I am initializing the base class
I am initializing the child class 
Sign up to request clarification or add additional context in comments.

3 Comments

Should Object.create be used here?
As OP speaks of "classes" and inheritance, I personally feel that prototype is more suited.
Maybe Jan meant to use MyChildClass.prototype = Object.create(MyBaseClass.prototype);. That would be a better approach for inheritance IMHO. Instantiating a new instance of the parent can have drawbacks.
1

jsFiddle Demo

Couple of things. extend really just adds on properties, it doesn't do much. So you need to have a function for your class ready, inherit from the base class, and then use extend on that classes prototype.

function MyChildClass(){};
MyChildClass.prototype = new MyBaseClass();
$.extend(MyChildClass.prototype, {
 init: function() {
    MyBaseClass.prototype.init();
    console.log('I am initializing the child class');
 }
});

Here is another approach that I like to use for inheritance - when the specificity of methods is going to be an issue - which is to store the base class in its own property

function MyChildClass(){};
MyChildClass.prototype = new MyBaseClass();
MyChildClass.prototype.base = new MyBaseClass();
$.extend(MyChildClass.prototype, {
 init: function() {
    this.base.init();
    console.log('I am initializing the child class');
 }
});

Comments

1

Another prototype based pattern to achieve this goal:

MyBaseClass = function(a) {
     this.a = a;
};

MyBaseClass.prototype = {
    init: function() {
        console.log('I am initializing the base class');
    }
};

MyChildClass = function() {};
MyChildClass.prototype = $.extend(new MyBaseClass(), {
    init: function() {
        this.super.init.call(this);
        console.log('init child');
    },
    super: MyBaseClass.prototype,
    constructor: MyChildClass
});

var a = new MyChildClass();
a.init();

Output:

I am initializing the base class
init child

Here this.super stores reference to base class.

9 Comments

Honest question : why are you specifying the constructor ?
@dystroy - I actually saw that in the jquery source code. I think it is because sometimes the constructor points to the wrong function at times (can't remember the exact scenario to get it to do that at the moment).
@dystroy To be able to use instanceof. a instanceof MyChildClass
There's a problem with your pattern : you lose the context in using this.super.init() or this.super.anyfunc(). This super looks like a bad idea.
@dystroy You are right, thank you. Well this is just another pattern, why not, some people use it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.