0

--SOLVED--

var deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10];
alert(deck.length);

function getDeck() {
    alert(deck);
}

When I run this in a website the first alert works but the second leaves an error message saying deck is undefined, I have tried other ways of writing this as well but they do not work, how do I access this array inside a function?

The idea is that it is a blackjack game and when I run the function newGame, it checks if there is less than 21 "cards" remaining. If so it "shuffles" the deck by resetting it to the way it was at the start:

function newGame() {
    if (deck.length <= 20) {
        var deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
    }
}

My full code: http://jsfiddle.net/cAWw2/ Thank you to everyone that left an answer or comment, removing var from the first line fixed it, I shall now learn about hoisting since many of the comments mention it. I have very very little knowledge of JavaScript at this point in time.

  • We'd need more code but you also probably should read more about "scope" in JavaScript. – Denys Séguret May 26 '14 at 06:43
  • 2
    Try sending us your code using http://jsfiddle.net/ – Pablo Jomer May 26 '14 at 06:44
  • Everything works fine when I run your code... – bobthedeveloper May 26 '14 at 06:53
  • Can you add the relevant code that calls `getDeck()` as that is the important factor. Not taking [**hoisting**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting) into consideration could be the issue. Hoisting moves the `var deck;` declaration to the top of the function scope it is in but leaves the assignment (`deck=[1,2,3,4,5,6,7,8,9,10,10,10];`) where it was lexically defined. So if you call `getDeck` before the assignment you will get `undefined`. It also helps if you can add a [**jsFiddle**](http://jsFiddle.net) demonstrating the issue. – Nope May 26 '14 at 06:58
  • 1
    @user3675304: You might need to post your actual code you are using to identify the problem. If you get `undefined` that is one issue, if you want to shuffle the array (as you state in your comments) that is another issue. Maybe one is causing the other but without the actual code in your question it will be a guessing game. – Nope May 26 '14 at 07:06
  • My full code: http://jsfiddle.net/cAWw2/ – user3675304 May 26 '14 at 07:12
  • 2
    @user3675304 Instead of updating with "solved", simply mark an answer as accepted. Please read [how does accepting an answer work?](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – h2ooooooo May 26 '14 at 07:28

2 Answers2

2

Based on new sample issue is with variable scope: you are declaring new local var desk inside newGame function when you likely want to change one in outer scope. Likely fix - remove var to change deck from outer (possibly global) scope:

function newGame() {
    if (deck.length <= 20) {
           deck = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
    }
}

Note (thanks to h2ooooooo): the 2 things together - locally defined var deck later in the function and than hoisted to the top of the function - creates "deck undefined" error when deck.length is used (which in most other language would be one from global scope, but in JavaScript it is declared later in the function and hoisted up with undefied as value).

JavaScript 'hoisting': functions are visible and useable before declaration later in the same scope, variables just visible at the beginning of the scope with undefined as value. So if you call getDeck before var deck is executed you'll get undefined instead of deck.

getDeck();// will fail here
var deck=[1,2,3,4,5,6,7,8,9,10,10,10];
alert(deck.length);
function getDeck()
  {alert(deck);}
getDeck();// will work  here
Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • Thank you for answering but I don't know if that helps because I need to change the array within the function. The idea is that if there is less than 20 "cards" remaining the deck will be "shuffled". if (x<=20) {var deck= [1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10,1,2,3,4,5,6,7,8,9,10,10,10,10];//the number value of each card in the deck } – user3675304 May 26 '14 at 06:55
  • @user3675304 no, it does not help. You need to update your post with sample that shows the behavior. As it was pointed in comments you need to learn about scope of variables in JavaScript. – Alexei Levenkov May 26 '14 at 07:10
  • @user3675304 The problem is still hoisting. Because you use `var deck` instead of `deck` you're refering to the local *scope variable* named `deck`, and **not** the *global* `deck` variable. Just remove `var`. You define variables *once* and *then* set them. Don't define them multiple times. – h2ooooooo May 26 '14 at 07:15
  • 1
    @h2ooooooo - declaring local variable with the same name as one in outer scope usually not called "hoisting"... – Alexei Levenkov May 26 '14 at 07:17
  • 1
    @AlexeiLevenkov No, but it hoists to the top of the function and therefore messes with the `deck` variable even though the card length is above 20. – h2ooooooo May 26 '14 at 07:18
  • @user3675304 you hiding global variable with newly declared local one with the same name (more than one case in your code). See edit. – Alexei Levenkov May 26 '14 at 07:18
  • Thank you, removing var fixed that problem, I shall now learn about this "hoisting" everyone's talking about. I've only joined my coding class 3 days ago so my knowledge is zero. – user3675304 May 26 '14 at 07:23
  • @h2ooooooo - thanks for good comment - inlined into the answer. – Alexei Levenkov May 26 '14 at 07:27
-1
var deck=[1,2,3,4,5,6,7,8,9,10,10,10];
function getDeck(){
    for (var i = 0; i < deck.length; i++){
         console.log(deck[i]);
    }
}

getDeck(); //remember to call the function
jhyap
  • 3,779
  • 6
  • 27
  • 47