简体   繁体   English

在forEach循环中使用Object.create

[英]Using Object.create in a forEach loop

I am writing a card game using javascript/html5 我正在使用javascript / html5编写纸牌游戏

I get the gamestate as an ajax request. 我将gamestate作为ajax请求。 this is JSON data that lists the players and what cards they have in their hand 这是JSON数据,列出了玩家以及他们手中的牌

I am trying to loop over each player and set the hand data as follows 我正在尝试遍历每个玩家并按如下方式设置手牌数据

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);
});

There are six canvases on the page. 页面上有六个画布。 One for each player 每个玩家一个

I am using Object.create to create a new "instance" of a hand. 我正在使用Object.create创建一只手的新“实例”。 And then calling the draw method, which lays out the images on the canvas 然后调用draw方法,该方法将图像布置在画布上

However, what actually happens is that each players data just gets added to the same instance 但是,实际上发生的是每个玩家数据仅被添加到同一实例中

ie each time I go round the forEach loop, the hand object just gets assigned more and more cards 也就是说,每次我绕过forEach循环时,手形对象都会被分配越来越多的牌

I would like to have a seperate instance for each player 我想为每个玩家设置一个单独的实例

So how do I achieve this? 那么我该如何实现呢?

I want to loop over the data and create a new hand for each iteration of the loop 我想遍历数据并为每次迭代创建新手

I am guessing that the hand variable has been hoisted out of the loop and so I get the same one each time? 我猜想手形变量已被吊起,所以每次都得到相同的值?

and this is what Hand looks like 这就是手的样子

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;
        });
    }
};

Your hand variable is not being hoisted out of the loop. 您的手形变量没有被吊出循环。 Javascript variables have function scope and you are already conveniently using a function inside your forEach loop. Javascript变量具有函数作用域,您已经可以方便地在forEach循环中使用一个函数。


What is Hand ? 什么是Hand The usual convention is having capitalized names represent constructor functions, but the Players and the Object.create make it look like Hand is just an object? 通常的约定是使用大写的名称表示构造函数,但是Players和Object.create使其看起来像Hand只是一个对象?

If Hand is already an object (and not a Constructor you are misusing) my best bet would be that initializeHand/setPosition are seting closed-over variables instead of accessing them via this . 如果Hand已经是一个对象(而不是您正在滥用的Constructor),那么最好的选择是initializeHand / setPosition设置封闭变量,而不是通过this进行访问。 (Of course, this is just a wild guess without looking at the Hand code) (当然,这只是在不看Hand代码的情况下的疯狂猜测)


After looking at your Hand code, I now think the problem is that the hands are sharing the faceDownCards , etc, arrays. 看完您的Hand代码后,我现在认为问题在于手共享faceDownCards等数组。 The base prototype should only be used for shared traits and the arrays and other instance-olny state should be set on initialization : 基本原型仅应用于共享特征,并且应在初始化时设置数组和其他instance-olny状态:

For a concrete example, change 举一个具体的例子,改变

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

to

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

ps.: All the Object.create going around is not exactly idiomatic Javascript. ps .:所有Object.create都是不完全惯用的Javascript。 But then, I guess you should have an Idea of what you are doing, right? 但是,我想您应该对自己的工作有所了解,对吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM