Reputation: 605
I'm having a problem with global variables in JavaScript. What I tried doing was declare the variable outside of the function, then changing it within a function, then calling in another function. From what I've read, this should have worked, but it's just giving me undefined. Here is my code to s card drawing game I'm making.
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!");
}
});
});
That is the code I tried and the variable I'm trying to pass is randSuit. what am I doing wrong?
Upvotes: 2
Views: 9070
Reputation: 57119
@Elliot Bonneville's and @jfriend00's answers are good, but here is a bit of explanation of the theory behind your local and global variables issue.
The way JavaScript works with global and local variables is that when the interpreter encounters an identifier, it is searching for it in the current scope (in your case: getRandCard
), and if it can't find it - the interpreter goes one scope above, and if it can't find it there - it goes two scopes above and so forth.
randSuit = randSuit;
In this line those identifiers will both refer to the same local variable, as the interpreter finds them both in the local scope, so effectively this line does nothing.
In order to refer to the global variable, you should create a reference to its scope:
var randSuit;
var that = this;
function getRandCard() {
...
}
Then, replace:
randSuit = randSuit;
with:
that.randSuit = randSuit;
Upvotes: 3
Reputation: 53291
Try this, it's a shortened version of your code which should work:
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);
}
I used a few arrays and a ternary operator to shorten your code considerably. I also eliminated the uncessary local randSuit
variable, which was scoped and overrode your global object.
Upvotes: 0
Reputation: 11415
When you redeclare randsuit inside the function, it is privatized to that function
var randSuit = 5; // not shared
function getRandCard() {
var randSuit = 3; // not shared
console.log(randSuit);
}
getRandCard();
console.log(randSuit);
If you want to share the output of randSuit
don't redeclare the variable
var randSuit = 5; // shared
function getRandCard() {
randSuit = 3; // shared
console.log(randSuit);
}
getRandCard();
console.log(randSuit);
A better option would be to modularize the cards variables and methods
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();
Upvotes: 1
Reputation: 707148
If you want to use a global variable, then define the variable globally and do NOT redefine it locally, just use it locally. When you redefine it locally, you create a new local variable with the same name that supercedes the global variable in that scope.
The rest of this is really a comment, but since one can't effectively include code in a comment, I'll post it part of an answer. You really need to apply DRY (don't repeat yourself) principles to your code. This is horribly repetitive:
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";
}
And could be replaced with this far less repetitive code:
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)];
Upvotes: 0
Reputation: 95242
You redeclared randSuit
inside the function; that declaration hides the global randSuit
, so your function is modifying its own local variable instead of the global one.
Upvotes: 2
Reputation: 6623
You are defining a global variable called randSuit
, but also a local variable with the same name. When you do randSuit = randSuit;
, effectively nothing happens, since both the left side and right side are referencing the local variable. You need to name them differently.
Upvotes: 4