2012-04-19 4 views
1

У меня проблема с глобальными переменными в JavaScript. То, что я пробовал делать, было объявить переменную за пределами функции, а затем изменить ее внутри функции, а затем вызвать другую функцию. Из того, что я читал, это должно было сработать, но это просто дало мне неопределенность. Вот мой код для игры с карточным рисунком, который я делаю.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. Что я делаю не так?

ответ

3

Вы определяете глобальную переменную с именем randSuit, но также - локальная переменная с тем же именем. Когда вы делаете randSuit = randSuit;, фактически ничего не происходит, так как левая и правая стороны ссылаются на локальную переменную. Вы должны назвать их по-разному.

2

Вы обновили randSuit внутри функции; эта декларация скрывает глобальный randSuit, поэтому ваша функция изменяет собственную локальную переменную вместо глобальной.

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, которая была изменена и переопределила ваш глобальный объект.

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(); 
2

@Elliot Bonneville-х и ответы @ jfriend00 являются хорошо, но вот немного объяснения теории позади вашей проблемы локальные и глобальные переменные.

Способ работы JavaScript с глобальными и локальными переменными заключается в том, что когда интерпретатор встречает идентификатор, он ищет его в текущей области (в вашем случае: getRandCard), и если он не может найти его - интерпретатор идет одна область выше, и если она не может найти ее там - она ​​проходит две области выше и так далее.

randSuit = randSuit; 

В этой строке эти идентификаторы оба относятся к одной и той же локальной переменной, так как интерпретатор находит их как в локальной области, так что эффективно эта линия не делает ничего.

Для того, чтобы обратиться к глобальной переменной, вы должны создать ссылку на его объем:

var randSuit; 
var that = this;  

function getRandCard() { 
    ... 
} 

Затем замените:

randSuit = randSuit; 

с:

that.randSuit = randSuit; 
+0

больше не актуальна, но вы не можете реально получить в 'randSuit' через' that' если не ' это 'окно'. – jli

+0

@jli true, если вы не объявите свои переменные следующим образом: 'this.randSuit = val;' –

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)]; 
+0

Если вы хотите быть очень хитрой, вы могли бы даже сделать это: '[" 1 "," 2 "," 3 "," 4 "," 5 "," 6 "," 7 "," 8 "," 9 "," Jack "," Queen "," King "," Ace "] [Math.floor (Math.random() *) 13)]; 'поскольку вы используете только переменную' cards'. знак равно –

Смежные вопросы