How to Establish Inheritance Between Objects in JavaScript?

I have the following code that creates two objects (ProfileManager and EmployerManager) where the object EmployerManager is supposed to inherit from the object ProfileManager. However, when I do alert(pm instanceof ProfileManager); it returns false.

function ProfileFactory(profileType) {
    switch(profileType)
    {
        case 'employer':
            return new EmployerManager();
            break;
    }
}

function ProfileManager() {
    this.headerHTML = null;
    this.contentHTML = null;
    this.importantHTML = null;

    this.controller = null;

    this.actions = new Array();
    this.anchors = new Array();
}

ProfileManager.prototype.loadData = function(action, dao_id, toggleBack) {

    var step = this.actions.indexOf(action);

    var prv_div = $('div_' + step - 1);
    var nxt_div = $('div_' + step);

    new Ajax.Request(this.controller, {
            method: 'get',
            parameters: {action : this.actions[step], dao_id : dao_id},
            onSuccess: function(data) {
                nxt_div.innerHTML = data.responseText;

                if(step != 1 && !prv_div.empty()) {
                    prv_div.SlideUp();
                }

                nxt_div.SlideDown();

                for(i = 1; i <= step; i++)
                {
                    if($('step_anchor_' + i).innerHTML.empty())
                    {
                        $('step_anchor_' + i).innerHTML = this.anchors[i];
                    }
                }
            }
        }
    )   
}

EmployerManager.prototype.superclass = ProfileManager;

function EmployerManager() {
    this.superclass();

    this.controller = 'eprofile.php';

    this.anchors[1] = 'Industries';
    this.anchors[2] = 'Employer Profiles';
    this.anchors[3] = 'Employer Profile';

    this.actions[1] = 'index';
    this.actions[2] = 'employer_list';
    this.actions[3] = 'employer_display';   
}

var pm = new ProfileFactory('employer');
alert(pm instanceof ProfileManager);

BTW, this is my very first attempt at Object-Oriented JavaScript, so if you feel compelled to comment on the stupidity of my approach please feel free to do so, but offer suggestions on how to approach the problem better.

Answers


I've been using something similar to Dean Edward's Base.js model. http://dean.edwards.name/weblog/2006/03/base/


Prototype supports (mimicing) class inheritance via the Object.extend() function.

However, it could be argued that trying to impose class-based inheritance on a language which doesn't support classes is an example of "when you only have a hammer, the whole world looks like a nail".


Thanks for all of the comments. However, the solution to the problem was found in making this change to the declaration of the EmployerManager:

function EmployerManager() {

    this.controller = 'eprofile.php';
    this.anchors = new Array('Industries', 'Employer Profiles', 'Employer Profile');
    this.actions = new Array('index', 'employer_list', 'employer_display'); 
}

EmployerManager.prototype = new ProfileManager;

Apparently JavaScript supports two different types of inheritance, function based and prototype based. The function based version is what I originally posted but could not make work because the EmployerManager could not see the loadData method that was part of ProfileManager's prototype.

This new example is prototype based and works now. EmployerManager is now an instance of ProfileManager.


In your code, pm is an instance of EmployerManager that has a superclass of ProfileManager. That seems backwards to me. Shouldn't ProfileManager have a superclass of EmployerManager?


I just wanted to interject that while JavaScript is an object oriented language, it does not have many of the features common in other popular OO languages. Conversely, it also has many features that other popular OO languages do not.

As you have already discovered inheritance is managed via prototype objects, rather than by class inheritance. However, the prototype object is not examined when using the "instanceof" operator. This means that JavaScript does not support polymorphism. At least not out of the box.

You can find libraries that will make JavaScript conform to the model of OOP that you're used to; if you're under the gun this might be the best solution. (Although no library is ever going to make a JavaScript object polymorphic when examined using "instanceof"; an isInstanceOf function would probably be necessary.) Or you could choose another language which does conform to that model of OOP, but you're probably working in a browser, so that's obviously not an option. Or you could answer the question, "how can I solve my problem without polymorphism?"


You should note that the same question has been asked (by me). Check out the answers on that post.


You can use new or Object.create to achieve classical inheritance

function A(){
    B.call(this);
}
function B(){
}

//there are 2 ways to make instanceof works
//1. use Object.create
A.prototype = Object.create(B.prototype);
//2. use new
//A.prototype = new B();

console.log(new A() instanceof B); //true

//make instanceof works
EmployerManager.prototype = Object.create(ProfileManager.prototype);
//add other prototype memebers
EmployerManager.prototype.superclass = ProfileManager;

console.log(new EmployerManager() instanceof ProfileManager); //true

Need Your Help

Efficiently organizing data into a readable .csv format

python optimization csv matrix

I am trying to figure out a better way to extract data from a large number of files, run additional calculations on some data, and finally format it into a something readable by a spreadsheet appli...

displaytag: suppress zeros in HTML table

java html jsp html-table displaytag

I have a HTML table that's generated in a JSP by the displaytag tag library. I would like to suppress any zeros that appear in the table, i.e. they should be replaced by a blank cell. Is there any