2012-12-07 153 views
7

Possible Duplicate:
set attribute with javascript super method調用父類中的方法從子類 - 的JavaScript

我試圖創建HTML5一個簡單的遊戲樂趣。我有一個應該是Player類的超類的實體類。

function Entity(x, y) { 

    this.x = x; 
    this.y = y; 

    this.tick = function() { 
     //Do generic stuff 
    } 
} 

function Player(x, y) { 

    this.parent.constructor.call(this, x, y); 

    this.tick = function() { 
     //Do player-specific stuff 
     this.parent.tick.call(this); 
    } 
} 

Player.prototype = new Entity(); 
Player.prototype.constructor = Player; 
Player.prototype.parent = Entity.prototype; 

的問題是在這條線:

this.parent.tick.call(this); 

我得到了鍍鉻的JavaScript控制檯顯示一個錯誤:「遺漏的類型錯誤:無法調用的未定義‘叫’」。

我不明白,我花了很長時間試圖找到類似問題的帖子。我對超類的構造函數的調用工作正常,但對超類'tick方法的調用不起作用。

我對製作遊戲很陌生,所以我不知道這是否是一個好的設置(從子類打勾調用超類打勾)。如果有更好,更典型的人使用的方式,請告訴。

謝謝。

+0

爲什麼你沒有原型上​​的通用東西?你可以在那裏輕鬆訪問它。 – Bergi

+0

JavaScript沒有經典的繼承,就像你從其他古典語言如java中使用。您應該閱讀原型繼承,並瞭解它與經典繼承之間的差異。 – Christoph

回答

7

適應this answer到您的代碼:

function Entity(x, y) { 

    this.x = x; 
    this.y = y; 

    this.tick = function() { 
     //Do generic stuff 
    } 
} 

function Player(x, y) { 

    this.parent.constructor.call(this, x, y); 

    var oldtick = this.tick; 
    this.tick = function() { 
     //Do player-specific stuff 
     oldtick.call(this); 
    } 
} 

Player.prototype = Object.create(Entity.prototype); 
Player.prototype.constructor = Player; 
Player.prototype.parent = Entity.prototype; 
+0

我有疑問。爲什麼我們需要在this.parent.constructor.call(this,x,y);'中傳遞'this'。那麼我知道,這會像這樣工作。但我沒有找到任何解釋。 –

+0

@VeerShrivastav:您需要傳遞該實例,否則構造函數將不知道在哪裏設置其屬性。 – Bergi

4

你的問題啓發了我環顧四周,我發現我的想法是a great article by Josh Gertzen這個概念。

function Class() { } 
Class.prototype.construct = function() {}; 
Class.extend = function(def) 
{ 
    var classDef = function() 
    { 
     if (arguments[0] !== Class) 
     { 
      this.construct.apply(this, arguments); 
     } 
    }; 
    var proto = new this(Class); 
    var superClass = this.prototype; 
    for (var n in def) 
    { 
     var item = def[n];      
     if (item instanceof Function) item.$ = superClass; 
     proto[n] = item; 
    } 
    classDef.prototype = proto; 
    classDef.extend = this.extend;  
    return classDef; 
}; 

在這之後你的情況是一樣簡單:

var Entity = Class.extend({ 
    tick: function() 
    { 
     alert('Entity tick'); 
    } 
}); 

var Player = Entity.extend({ 
    tick: function() 
    { 
     alert('Player tick'); 
     arguments.callee.$.tick.call(this); 
    } 
}); 

p = new Player(); 
p.tick(); 

這將提醒Player tick然後

我大搖大擺地從他的文章中的一些代碼,以建立一個extends方法的類複製Entity tick

+10

看起來像對我來說是一個過度複雜:-) – Bergi

+0

+1的努力,雖然Bergi答案更清潔。 – WTK

+2

如果這是應用程序中唯一的超類調用,那當然是過度複雜的。但是我發現第二塊代碼比其他方法更清晰。你只需要複製粘貼第一個塊然後忘記它;沒有更多關於原型的想法:-) – Mark