如何将对象分配给另一个对象中的数组?

时间:2014-05-26 07:11:49

标签: javascript

我正在接受二十一点挑战并提出我自己的代码。所以这就是我迄今为止所拥有的......我的卡片生成器......

var card = {
    suit: null,
    face: null,
    value: null,
    generateSuit: function (x) {
        if (x == 0) this.suit = 'Clubs';
        if (x == 1) this.suit = 'Diamonds';
        if (x == 2) this.suit = 'Hearts';
        if (x == 3) this.suit = 'Spades';
    },
    generateFace: function (y) {
        if (y > 1 && y < 11) this.face = y,
        this.value = y;
        else {
            if (y == 1) this.face = 'Ace', this.value = 1;
            if (y == 11) this.face = 'Jack', this.value = 10;
            if (y == 12) this.face = 'Queen', this.value = 10;
            if (y == 13) this.face = 'King', this.value = 10;
        };
    },
    generateCard: function () {
        var x = Math.floor(Math.random() * 4);
        var y = Math.floor(Math.random() * 13 + 1);
        this.generateSuit(x);
        this.generateFace(y);
    },
}

这样做很好,我只是把它包括在内,因为下一部分让我难过,所以我想我什么也不留。

以下是事情向南 - 在我的'手'中(下一篇),我正在使用'generateCard()'函数设置'card'的值,然后将它们存储在名为'storecard []的数组中”。

var hand = {
    storecard: [],
    count: 0,
    total: 0,
    hitCard: function () {
        this.count += 1;
        card.generateCard();
        this.storecard[this.count] = Object.create(card);
        this.total += this.storecard[this.count].value;
        this.logHand();
    },
    logHand: function () {
        console.log(this.storecard[this.count].face + ' of ' + this.storecard[this.count].suit);
        console.log('Value = ' + this.storecard[this.count].value);
        console.log('Count = ' + this.count);
        console.log('Hand Total = ' + this.total);
    }
}

这个想法是每次卡片被击中(添加到手中),“手”会将它(及其所有属性 - 套装,价值等)藏在storecard[index == hand count, clever eh?]

这样,我可以随时访问storecard[index]来检索手中任何卡片的任何属性。

嗯,不是那么多。运行代码,那个阵列是唯一能够沾沾自喜的东西......

var me = Object.create(hand);
var dealer = Object.create(hand);

me.hitCard();
me.hitCard();

我的'logHand()'函数表明一切正常!

"5 of Hearts"     
"Value = 5"       
"Count = 1"       
"Hand Total = 5"  
"2 of Clubs"      
"Value = 2"       
"Count = 2"       
"Hand Total = 7"

但唉,不知何故 - 'storecard'阵列失败了。经过进一步检查,我们发现:

me.storecard[1].value
2
me.storecard[2].value
2

storecard[1]应该抱着我的心,但被2个俱乐部覆盖了!如果这还不够恐怖......

dealer.storecard[1].value
2
dealer.storecard[1].value
2

我还没有触及经销商的对象!

现在我的手和经销商手中的每一个变量都与现实一致 - 阵列是唯一的问题。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:5)

问题在于您对Object.create()所做的事情的期望。

它创建了对象的浅层克隆。数组是通过引用分配的,而不是值。

例如

var arrayOne = [];
var arrayTwo = arrayOne;
arrayOne.push('3');
alert(arrayTwo[0]); // This will give you 3. Both variables are pointing to the same array

同样如此:

   var handTemplate = {
       childArray: []
   };

   var handOne = Object.create(handTemplate);
   var handTwo = Object.create(handTemplate);
   // At this point, handTemplate, handOne and handTwo all point to the same array

   handOne.childArray.push('3');
   alert(handTwo.childArray([0])); // Again, you'll see 3, because there's only one array

一种解决方案是使用专用函数创建hand

function createHand() {
    return {
        storecard: [], // Now we get a brand new array every time createHand is called
        count: 0,
        total: 0,
        hitCard: function () {
            this.count += 1;
            card.generateCard();
            this.storecard[this.count] = Object.create(card);
            this.total += this.storecard[this.count].value;
            this.logHand();
        },
        logHand: function () {
            console.log(this.storecard[this.count].face + ' of ' + this.storecard[this.count].suit);
            console.log('Value = ' + this.storecard[this.count].value);
            console.log('Count = ' + this.count);
            console.log('Hand Total = ' + this.total);
        }
    };
}

var me     = createHand();
var dealer = createHand();

答案 1 :(得分:1)

这是一种不同的方法,但这是一种很好的方法 我以一种你可以学到的东西编写代码 例如..你可以完全摆脱count变量,因为它等于storecard.length 但是请注意,你仍需要防止出现卡片。您可以通过先生成所有卡片,将其放入一个数组,然后随机拼接出来,直到堆叠为空来轻松完成。

var Card = function () {
    this.suit = null;
    this.face = null;
    this.value = null;
    this.generateCard();
};

Card.prototype = {
    generateSuit: function (x) {
        this.suit = ["Clubs", "Diamonds", "Hearts", "Spades"][x];
    },
    generateFace: function (y) {
        this.value = Math.min(10, y);
        switch (y) {
            case 1:
                this.face = "Ace";
                break;
            case 11:
                this.face = "Jack";
                break;
            case 12:
                this.face = "Queen";
                break;
            case 13:
                this.face = "King";
                break;
            default:
                this.face = y;
                break;
        }
    },
    generateCard: function () {
        this.generateSuit(Math.floor(Math.random() *4));
        this.generateFace(Math.floor(Math.random() *13 +1));
    }
}

var Hand = function () {
    this.storecard = [];
    this.count = 0;
    this.total = 0;
};

Hand.prototype = {
    hitCard: function () {
        this.count++;
        var card = new Card();
        this.storecard.push(card);
        this.total += card.value;
        this.logHand();
    },
    logHand: function () {
        var card = this.storecard[this.storecard.length -1];
        console.log(card.face + ' of ' + card.suit);
        console.log('Value = ' + card.value);
        console.log('Count = ' + this.count);
        console.log('Hand Total = ' + this.total);
    }
}

结果将是:

> var me = new Hand();
undefined
> var dealer = new Hand();
undefined
> me.hitCard();
Ace of Hearts
Value = 1
Count = 1
Hand Total = 1
undefined
> me.hitCard();
6 of Diamonds
Value = 6
Count = 2
Hand Total = 7
undefined
> me.storecard
[ { suit: 'Hearts',
    face: 'Ace',
    value: 1 },
  { suit: 'Diamonds',
    face: 6,
    value: 6 } ]