如何在JavaScript中建立对象之间的继承?

时间:2008-11-21 18:19:03

标签: javascript oop inheritance

我有以下代码创建两个对象(ProfileManager和EmployerManager),其中对象EmployerManager应该从对象ProfileManager继承。 但是,当我做警报时(pm instanceof ProfileManager);它返回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);
顺便说一句,这是我第一次尝试面向对象的JavaScript,所以如果你觉得有必要对我的方法的愚蠢做评论,请随意这样做,但提供有关如何更好地解决问题的建议。

7 个答案:

答案 0 :(得分:2)

我一直在使用与Dean Edward的Base.js模型类似的东西。 http://dean.edwards.name/weblog/2006/03/base/

答案 1 :(得分:2)

Prototype通过Object.extend()函数支持(模仿)类继承。

然而,可以说,试图将基于类的继承强加于不支持类的语言是“当你只有一把锤子时,整个世界看起来像钉子”的例子。

答案 2 :(得分:1)

感谢所有评论。但是,在对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;

显然,JavaScript支持两种不同类型的继承,基于函数和基于原型。基于函数的版本是我最初发布但无法工作的版本,因为EmployerManager无法看到作为ProfileManager原型的一部分的loadData方法。

这个新示例基于原型并且现在可以使用。 EmployerManager现在是ProfileManager的一个实例。

答案 3 :(得分:0)

在您的代码中,pm是具有ProfileManager超类的EmployerManager的实例。这对我来说似乎是倒退。 ProfileManager不应该有一个EmployerManager的超类吗?

答案 4 :(得分:0)

我只想插入,虽然JavaScript是一种面向对象的语言,但它没有其他流行的OO语言中常见的许多功能。相反,它也有许多其他流行的OO语言没有的功能。

正如您已经发现的,继承是通过原型对象管理的,而不是通过类继承来管理的。但是,使用“instanceof”运算符时不会检查原型对象。这意味着JavaScript不支持多态。至少没有开箱即用。

您可以找到能够使JavaScript符合您习惯的OOP模型的库;如果你在枪下,这可能是最好的解决方案。 (虽然在使用“instanceof”进行检查时,没有任何库可以使JavaScript对象具有多态性;但是可能需要使用isInstanceOf函数。)或者您可以选择另一种符合该OOP模型的语言,但您可能正在工作在浏览器中,这显然不是一个选项。或者你可以回答这个问题,“如何在没有多态的情况下解决我的问题?”

答案 5 :(得分:0)

你应该注意到same question has been asked(由我)。查看该帖子的答案。

答案 6 :(得分:0)

您可以使用Object.create来实现经典继承

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