在forEach循环中使用Object.create

时间:2011-09-11 16:57:14

标签: javascript object-create

我正在使用javascript / html5

写一个纸牌游戏

我将游戏状态作为ajax请求。这是列出玩家的JSON数据以及他们手中有哪些牌

我正在尝试遍历每个玩家并按如下方式设置手部数据

gameState.Players.forEach(function (player, i) {    
    var inx = i + 1;
    var canvas = document.getElementById("player" + inx);
    var ctx = canvas.getContext("2d");

    var hand = Object.create(Hand);
    hand.initialiseHand(player.Hand);
    hand.setPosition(10, 10);
    hand.draw(ctx);
});

页面上有六幅画布。每个玩家一个

我正在使用Object.create来创建一个手的新“实例”。然后调用draw方法,它在画布上放置图像

然而,实际发生的是每个玩家数据都被添加到同一个实例

即。每次我绕过forEach循环,手对象只会被分配越来越多的卡

我想为每个玩家设一个单独的实例

那我该如何实现呢?

我想循环数据并为循环的每次迭代创建一个新手

我猜测手变量已经被循环提升,所以每次都得到相同的变量?

这就是Hand的样子

var Hand = {

    faceDownCards: [],
    faceUpCards: [],
    inHandCards: [],

    initialiseHand: function (handData) {
        handData.FaceDownCards.forEach(function (c, i) {
            this.faceDownCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
        }, this);

        handData.FaceUpCards.forEach(function (c, i) {
            this.faceUpCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
        }, this);

        handData.InHandCards.forEach(function (c, i) {
            this.inHandCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
        }, this);

    },

    draw: function (context) {
        this.faceDownCards.forEach(function (c, i) {
            c.draw(context);
        });

        this.faceUpCards.forEach(function (c, i) {
            c.draw(context);
        });

        this.inHandCards.forEach(function (c, i) {
            c.draw(context);
        });
    },

    setPosition: function (x, y) {
        this.x = x;
        this.y = y;
        this.faceDownCards.forEach(function (c, i) {
            c.setPosition(x + i * 70, y);
        });
        this.faceUpCards.forEach(function (c, i) {
            c.setPosition(x + i * 70, y + 60);
        });
        this.inHandCards.forEach(function (c, i) {
            c.setPosition(x + i * 20, y + 80);
            //c.rotation = 3;
        });
    }
};

1 个答案:

答案 0 :(得分:1)

你的手变量被提升出循环。 Javascript变量具有函数范围,您已经方便地在forEach循环中使用了一个函数。


什么是Hand?通常的惯例是大写的名称代表构造函数,但是Players和Object.create使它看起来像Hand只是一个对象?

如果Hand已经是一个对象(而不是你滥用的构造函数),我最好的选择是initializeHand / setPosition正在设置封闭变量,而不是通过this访问它们。 (当然,这只是一个疯狂的猜测而不看Hand代码)


在查看了您的Hand代码之后,我现在认为问题在于手是在共享faceDownCards等数组。基本原型应仅用于共享特征,并且应在初始化时设置数组和其他instance-olny状态:

有关具体示例,请更改

handData.FaceDownCards.forEach(function (c, i) {
    this.faceDownCards.push(Object.create(Card, pd({ rank: c.Rank, suit: c.Suit })));
}, this);

 this.faceDownCards = handData.FaceDownCards.map(function (c, i) {
     return Object.create(Card, pd({ rank: c.Rank, suit: c.Suit }));
 });

ps。:所有围绕的Object.create并不完全是惯用的Javascript。但是,我猜你应该知道你在做什么,对吗?