7

可能重复:
使用 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);

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

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

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

谢谢。

4

2 回答 2

7

将此答案改编为您的代码:

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;
于 2012-12-07T12:19:05.660 回答
4

你的问题启发了我环顾四周,我发现我认为是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

于 2012-12-07T12:30:13.963 回答