Question

I'd like to do some inheritance using Javascript. The problem is I don't know how to keep the A class prototype on the inherited object.

Here is my code :

function Base() {
    this.attribute1 = null;
}

Base.prototype = {
    baseFunction: function() {}
};

function SubBase()
{
    Base.call(this); // Constructor call
    this.baseFunction();
    this.subBaseFunction();
}

SubBase.prototype = Base.prototype;
SubBase.prototype = {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
}

With that way I erase Base.prototype but I don't want to.

I tried SubBase.prototype.__proto__ = Base.prototype; but it is apparently too slow.

I know I can do (but too long to write and not that clean for me) :

SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};

How can I do it/write it better ?

Was it helpful?

Solution

First, you aren't actually inheriting from Base... you're just adding functions to it.

SubBase.prototype = Base.prototype;
SubBase.prototype.foo = true;
alert(Base.prototype.foo);

To set up the inheritance chain, you need to assign an instance of base as the prototype:

SubBase.prototype = new Base();

Then you augment it, just like you have in your post:

SubBase.prototype.newFunction = function () { };

One weakness of doing inheritance this way is that your base class constructor can't receive arguments. If you need that, then you need to use Object.create to set up the inheritance, and manually call your base class constructor:

function Base(x) {
    alert(x);
};
Base.prototype.baseFunction = function () {
    alert('called method from base class');
};

function SubBase(x) {
    Base.call(this, x);
};
SubBase.prototype = Object.create(Base.prototype);

var instance = new SubBase(1);
instance.baseFunction();

OTHER TIPS

Instead of this:

SubBase.prototype = Base.prototype;
SubBase.prototype = {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
}

you need to add each additional method onto the existing prototype object to avoid overwriting the Base.prototype you just put there:

// establish the prototype we're inheriting from
// make a new object into the prototype so when we change it, it 
// doesn't change the original
SubBase.prototype = Object.create(Base.prototype);

// now add more methods onto the inherited prototype
SubBase.prototype.subBaseFunction = function() {};
SubBase.prototype.subBaseOtherFunction = function() {};

Note: you also don't want to just assign Base.prototype because then when you change SubBase.prototype, you'll actually be changing both objects (an object assignment is just a reference). So here, I'm using Object.create(Base.prototype) to create a copy of that prototype.


Many libraries support some sort of extend() function that copies properties from one object to another. That lets you define a separate object of methods and then "add" it to the existing prototype, but this functionality isn't built-in to plain javascript.

For example in jQuery, you can do this:

// establish the prototype we're inheriting from
SubBase.prototype = Object.create(Base.prototype);

jQuery.extend(SubBase.prototype, {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
});

Or, updated in 2016, ES6 contains an Object.assign() function that will copy properties from one object to another:

Object.assign(SubBase.prototype, {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
});

Or, you can make your own function that will copy properties from one object to another in only a few lines of code.


Or, the same code in plain javascript:

// copy properties from src to target
function copyProperties(target, src) {
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            target[prop] = src[prop];
        }
    }
    return(target);
}

// establish the prototype we're inheriting from
SubBase.prototype = Object.create(Base.prototype);

copyProperties(SubBase.prototype, {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
});

Here's the style I typically use:

function Base() {
    this.attribute1 = null;
}

Base.prototype = {
    baseFunction: function() {}
};

function SubBase()
{
    Base.apply(this, arguments); // Constructor call with arguments
}

(function() {
    var proto = SubBase.prototype = Object.create(Base.prototype);
    proto.constructor = SubBase;
    proto.subBaseFunction = function() {
        // code here
    };
    proto.subBaseOtherFunction = function() {
        // code here
    };
})();

You could use jQuery.extend() for this:

SubBase.prototype = {
    subBaseFunction: function() {},
    subBaseOtherFunction: function() {}
};

$.extend(SubBase.prototype, Base.prototype);

See: http://jsfiddle.net/dd6UC/

jQuery.extend() docs: http://api.jquery.com/jquery.extend/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top