修改对象属性的方法中的 JavaScript 变量

JavaScript Variable in method modifying object's attribute?

本文关键字:JavaScript 变量 方法 属性 修改 对象      更新时间:2023-09-26

我正在尝试用JavaScript创建一个扑克游戏。我认为测试刷新的功能工作得很好,直到我在方法运行后显示手。如果有同花顺,这个函数应该显示用户的全手,然后只显示它下面的同花顺。相反,它只显示同花顺,然后再次显示其下方的同花顺:

var $ = function (id) { return document.getElementById(id); };
var test = function() {
    var deck = new POKER.Deck(); //creates deck
    var hand = new POKER.Hand(); //creates hand
    //----------------TEST HAND UNTIL FLUSH-----------------
    while (hand.getValue() != POKER.HAND_TYPE.FLUSH) {
        deck.refreshDeck(); //refresh deck with new cards
        for (var i = 0; i < 7; ++i) { //populate hand
            hand.addCard(deck.dealCard());
        }
        console.log(hand.size() + " before"); //only for debugging. Prints "7 before"
        hand.testFlush();
        console.log(hand.size() + " after"); //only for debugging. Result unexpected
        if (hand.getValue() == POKER.HAND_TYPE.FLUSH) { //if hand has a flush
            for (var j = 0; j < hand.size(); j++) { //display full hand
                var img = document.createElement("img");
                var card = hand.getCardAtIndex(j);
                img.src = card.getImage();
                $("images").appendChild(img);
            }
            for (var k = 0; k < 5; k++) { //display flush hand
                var img2 = document.createElement("img");
                var card2 = hand.getValueCardAtIndex(k);
                img2.src = card2.getImage();
                $("handImg").appendChild(img2);
            }
            break;
        } else {
            hand.empty();
        }
    }
  
};
window.onload = function() {
    test();
};

第二个控制台.log语句打印出"4 后",直到 testFlush 方法检测到刷新,最终结果为"5 后"。

测试冲洗方法:

POKER.Hand.prototype.testFlush = function() {
    //first, sort cards by rank so that the highest flush is 
    //taken if there are more than five cards of the same suit
    this.sortByRank();
    this.sortBySuit();
    var tempHand = this.cards; //modifiable version of this.cards
    var NUM_OF_TESTS = 3; //only 3 loops required to test for all possible flushes
    var LAST_CARD_INDEX = 4; //represents the fifth card, or index 4
    var MAX_CARDS = 5; //maximum cards possible in a hand (valueCards)
    for (var i = 1; i <= NUM_OF_TESTS; i++){
        //check if 1st and 5th cards are the same suit
        if(tempHand[0].getSuit() == tempHand[LAST_CARD_INDEX].getSuit()){
            this.value = POKER.HAND_TYPE.FLUSH;
            while(tempHand.length != MAX_CARDS){ //remove last card in tempHand until there are only five cards
                tempHand.pop();
            }
            this.valueCards = tempHand;
        }else{
            tempHand.splice(0,1); //removes first card from the temporary hand
        }
    }
};

测试函数中"hand.size()"所做的只是"return this.cards.length"。所以我不明白的是,当testFlush方法只改变临时变量tempHand时,它是如何改变对象属性"this.cards"的。

手对象:

POKER.Hand = function(){
    this.cards = [];
    this.value; //integer that corresponds to the POKER.HAND_TYPE
    this.valueCards = []; //array of the five cards that corresponds only to this.value
};

手的大小方法:

POKER.Hand.prototype.size = function() {
    return this.cards.length;
};

问题是这一行:

var tempHand = this.cards; //modifiable version of this.cards

将数组或对象分配给变量不会复制它。该变量是对同一数组的引用,因此tempHand.pop()也会修改this.cards。您可以使用.slice()创建数组的副本:

var tempHand = this.cards.slice();