[英]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.