从子类调用超类方法 - JavaScript

时间:2012-12-07 11:37:21

标签: javascript inheritance canvas subclass superclass

  

可能重复:
  set attribute with javascript super method

我正在尝试用HTML5创建一个简单的游戏以获得乐趣。我有一个Entity类,它应该是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);

我在Chrome的JavaScript控制台中显示错误:“未捕获的TypeError:无法调用未定义的方法'调用'。

我没有得到它,我花了很长时间试图找到类似问题的帖子。我对超类'构造函数的调用工作正常但是对超类'tick方法的调用不起作用。

我对制作游戏非常陌生,所以我不知道这是否是一个好的设置(从子类tick调用超类tick)。如果有更好,更典型的方式供人们使用,请告诉我们。

感谢。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分:4)

你的问题激励我环顾四周,我发现了我对a great article by Josh Gertzen这个概念的看法。

我公开抄袭他的文章中的一些代码,以便在类上设置extends方法:

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然后提醒Entity tick