2

JavaScript のグローバル変数に問題があります。私が試したのは、関数の外側で変数を宣言し、関数内で変数を変更してから、別の関数を呼び出すことでした。私が読んだことから、これはうまくいったはずですが、未定義になっているだけです。これが、私が作成しているカード描画ゲームのコードです。

var randSuit;
function getRandCard() {
    var randNum;
    var randSuit;
    var randVal;
    randNum = Math.floor(Math.random()*13)+1;
    if (randNum == 1) {
        randVal = "2";
    } else if (randNum == 2) {
        randVal = "3";
    } else if (randNum == 3) {
        randVal = "4";
    } else if (randNum == 4) {
        randVal = "5";
    } else if (randNum == 5) {
        randVal = "6"; 
    } else if (randNum == 6) {
        randVal = "7";
    } else if (randNum == 7) {
        randVal = "8";
    } else if (randNum == 8) {
        randVal = "9"; 
    } else if (randNum == 9) {
        randVal = "10";
    } else if (randNum == 10) {
        randVal = "Jack";
    } else if (randNum == 11) {
        randVal = "Queen";
    } else if (randNum == 12) {
        randVal = "King";
    } else if (randNum == 13) {
        randVal = "Ace";
    }

    randNum = randNum = Math.floor(Math.random()*4)+1;

    if (randNum == 1) {
        randSuit = "Hearts";
    } else if (randNum == 2) {
        randSuit = "Clubs";
    } else if (randNum == 3) {
        randSuit = "Spades";
    } else if (randNum == 4) {
        randSuit = "Diamonds";
    }

    console.log(randSuit);
    var randCard = (randVal + " of " + randSuit);
    //Return the Value of the randomly chosen Card.
    return (randCard);
}

//This function calls the random card from the function above, then applies logic to see if it's the same, then outputs the result.
$(function() {
    $('#drawCard').click(function() {

        var e = document.getElementById("faceValue");
        var faceValue = e.options[e.selectedIndex].text;
        var e = document.getElementById("suit");
        var suit = e.options[e.selectedIndex].text;

        $('#oneCardContainer').slideDown('slow');
        var pickedCard = (faceValue + " of " + suit);

        var randCard = getRandCard();
        console.log (randSuit);

        if (pickedCard == randCard) {
            $("#oneCardResults").val("You Chose a " + pickedCard + " and got a " + randCard + ". \nYou Win!");
        } else if (pickedCard != randCard) {

            $("#oneCardResults").val("You Chose a " + pickedCard + " and got a " + randCard + ". \nYou Lose!");

        }
    });
});

これが私が試したコードで、渡そうとしている変数は randSuit です。私は何を間違っていますか?

4

6 に答える 6

4

というグローバル変数を定義していますrandSuitが、同じ名前のローカル変数も定義しています。するとrandSuit = randSuit;、左側と右側の両方がローカル変数を参照しているため、事実上何も起こりません。それらに別の名前を付ける必要があります。

于 2012-04-19T02:06:10.730 に答える
3

@Elliot Bonneville と @jfriend00 の回答は適切ですが、ローカル変数とグローバル変数の問題の背後にある理論について少し説明します。

JavaScript がグローバル変数とローカル変数で動作する方法は、インタープリターが識別子に遭遇すると、現在のスコープ (あなたの場合: getRandCard) でそれを検索し、それが見つからない場合、インタープリターは 1 つ上のスコープに移動し、そこで見つからない場合は、2 つ上のスコープに移動します。

randSuit = randSuit;

この行では、これらの識別子は両方とも同じローカル変数を参照します。インタープリターは両方ともローカルスコープで見つけるため、この行は事実上何もしません。

グローバル変数を参照するには、そのスコープへの参照を作成する必要があります。

var randSuit;
var that = this;    

function getRandCard() {
    ...
}

次に、次を置き換えます。

randSuit = randSuit;

と:

that.randSuit = randSuit;
于 2012-04-19T02:15:47.383 に答える
2

randSuit関数内で再宣言しました。その宣言は global を隠しているrandSuitため、関数はグローバル変数ではなく独自のローカル変数を変更しています。

于 2012-04-19T02:06:52.270 に答える
1

関数内で randsuit を再宣言すると、その関数にプライベート化されます

var randSuit = 5; // not shared
function getRandCard() {
    var randSuit = 3; // not shared
    console.log(randSuit);
}
getRandCard();
console.log(randSuit);

http://jsfiddle.net/PbBph/

出力を共有したい場合はrandSuit、変数を再宣言しないでください

var randSuit = 5; // shared
function getRandCard() {
    randSuit = 3; // shared
    console.log(randSuit);
}
getRandCard();
console.log(randSuit);

http://jsfiddle.net/PbBph/1/

より良いオプションは、カードの変数とメソッドをモジュール化することです

var cardStack = (function () {
   var randSuit; // protected from global

   return {
      getRandSuit: function () { return randSuit; }, // but still readable
      getRandCard: function () { .... }
   };

}());

var card = cardStack.getRandCard();
    suit = cardStack.getRandSuit();
于 2012-04-19T02:12:54.670 に答える
0

これを試してみてください。これは、動作するはずのコードの短縮版です。

var randSuit;
function getRandCard() {
    var randNum, randVal;

    var upperCards = ["Jack", "Queen", "King", "Ace"];
    var suits = ["Hearts", "Clubs", "Spades", "Diamonds"];

    randNum = Math.floor(Math.random()*13)+1;
    (randNum < 10) ? randVal++ : randVal = upperCards[randNum-10];

    randSuit = suits[Math.floor(Math.random()*4)];

    // return the value of the randomly chosen card.
    return (randVal + " of " + randSuit);
}

コードを大幅に短縮するために、いくつかの配列と三項演算子を使用しました。randSuitまた、スコープが設定され、グローバル オブジェクトを上書きする不要なローカル変数も削除しました。

于 2012-04-19T02:12:18.863 に答える
0

グローバル変数を使用する場合は、変数をグローバルに定義し、ローカルで再定義せず、ローカルでのみ使用してください。ローカルで再定義すると、そのスコープ内のグローバル変数に取って代わる同じ名前の新しいローカル変数が作成されます。


これの残りの部分は実際にはコメントですが、コメントにコードを効果的に含めることはできないため、回答の一部として投稿します。DRY (同じことを繰り返さないでください) の原則をコードに適用する必要があります。これは恐ろしく繰り返されます:

randNum = Math.floor(Math.random()*13)+1;
if (randNum == 1) {
    randVal = "2";
} else if (randNum == 2) {
    randVal = "3";
} else if (randNum == 3) {
    randVal = "4";
} else if (randNum == 4) {
    randVal = "5";
} else if (randNum == 5) {
    randVal = "6"; 
} else if (randNum == 6) {
    randVal = "7";
} else if (randNum == 7) {
    randVal = "8";
} else if (randNum == 8) {
    randVal = "9"; 
} else if (randNum == 9) {
    randVal = "10";
} else if (randNum == 10) {
    randVal = "Jack";
} else if (randNum == 11) {
    randVal = "Queen";
} else if (randNum == 12) {
    randVal = "King";
} else if (randNum == 13) {
    randVal = "Ace";
}
randNum = randNum = Math.floor(Math.random()*4)+1;

if (randNum == 1) {
    randSuit = "Hearts";
} else if (randNum == 2) {
    randSuit = "Clubs";
} else if (randNum == 3) {
    randSuit = "Spades";
} else if (randNum == 4) {
    randSuit = "Diamonds";
}

そして、このはるかに少ない反復コードに置き換えることができます:

var cards = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "Jack", "Queen", "King", "Ace"];
randVal = cards[Math.floor(Math.random() * cards.length)];

var suits = ["Hearts", "Clubs", "Spades", "Diamonds"];
randSuit = suits[Math.floor(Math.random() * suits.length)];
于 2012-04-19T02:18:15.937 に答える