2008-11-21 67 views
1

我有以下代碼創建兩個對象(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非常的第一次嘗試,所以如果你覺得有必要對我的做法的愚蠢評論請隨時做,但就如何處理這個問題的建議更好。

回答

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的一個實例。

0

在您的代碼中,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

2

Prototype通過Object.extend()函數支持(模仿)類繼承。

但是,有人可能會認爲,試圖對不支持類的語言強加基於類的繼承是「當你只有一把錘子,整個世界看起來像釘子」的例子。

0

我只是想介紹一下,雖然JavaScript是一種面向對象的語言,但它並沒有很多其他常用OO語言中常見的功能。相反,它也有許多其他流行的面嚮對象語言所沒有的功能。

正如你已經發現繼承是通過原型對象而不是類繼承來管理的。但是,使用「instanceof」運算符時不會檢查原型對象。這意味着JavaScript不支持多態。至少不是開箱即用的。

您可以找到使JavaScript符合您習慣的OOP模型的庫;如果你在槍下,這可能是最好的解決方案。 (雖然在使用「instanceof」進行檢查時,沒有任何庫會創建JavaScript對象多態;但是可能需要使用isInstanceOf函數。)或者,您可以選擇符合OOP模型的其他語言,但您可能正在工作在瀏覽器中,這顯然不是一種選擇。或者你可以回答這個問題,「我怎麼能解決我的問題沒有多態性?」

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