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

问题描述:

我有以下代码创建两个对象(ProfileManager和EmployerManager),其中对象EmployerManager应该从对象ProfileManager继承。 但是,当我做alert(pm instanceof ProfileManager)时;它返回false。如何在JavaScript中建立对象之间的继承关系?

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非常的第一次尝试,所以如果你觉得有必要对我的做法的愚蠢评论请随时做,但就如何处理这个问题的建议更好。

感谢您的所有意见。然而,问题的解决作出这种改变的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的一个实例。

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

在您的代码中,pm是EmployerManager的一个实例,它拥有ProfileManager的超类。这似乎倒退了。不应该ProfileManager有EmployerManager的超类吗?

+0

的超从我的理解是父类。由于ProfileManager是EmployerManager的父代,因此ProfileManager是超类。 – 2008-11-21 19:51:51

+0

这导致pm instanceof EmployerManager返回true,pm instanceof ProfileManager返回false。 – 2008-11-21 23:29:23

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

但是,有人可能会认为,试图对不支持类的语言强加基于类的继承是“当你只有一把锤子,整个世界看起来像钉子”的例子。

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

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

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

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

您可以使用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