2012-12-07 109 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