Noah Goodrich
Noah Goodrich

Reputation: 25263

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.

Upvotes: 1

Views: 363

Answers (7)

cuixiping
cuixiping

Reputation: 25449

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

Upvotes: 0

pc1oad1etter
pc1oad1etter

Reputation: 8617

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

Upvotes: 0

Noah Goodrich
Noah Goodrich

Reputation: 25263

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.

Upvotes: 1

Benry
Benry

Reputation: 5298

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?"

Upvotes: 0

D&#243;nal
D&#243;nal

Reputation: 187399

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".

Upvotes: 2

Mr. Muskrat
Mr. Muskrat

Reputation: 23723

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?

Upvotes: 0

EndangeredMassa
EndangeredMassa

Reputation: 17528

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

Upvotes: 2

Related Questions