7

重複の可能性:
javascriptスーパーメソッドで属性を設定

楽しみのために HTML5 で簡単なゲームを作成しようとしています。Player クラスのスーパークラスであるはずの Entity クラスがあります。

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 コンソールに「Uncaught TypeError: Cannot call method 'call' of undefined」というエラーが表示されます。

よくわかりません。同様の問題の投稿を探すのに長い時間を費やしました。スーパークラスのコンストラクターへの呼び出しは正常に機能しますが、スーパークラスの 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

あなたの質問は私に周りを見回すように促しました、そして私はこの概念についてのJoshGertzenによる素晴らしい記事であると私が思うものを見つけました。

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 に答える