2013-09-07 3 views
0

Может ли кто-нибудь объяснить мне, почему этот код иногда входит в бесконечный цикл (предположительно из циклов while) и выдает окно браузера? Это как-то связано с while(userChoice != randNumber), не имеет ли этого достаточного конца?Почему этот код иногда приводит к краху браузера?

var check = function(userChoice) { 
     while ((isNaN(userChoice)) || (userChoice > 100) || (userChoice < 1) || (userChoice %1 !== 0)) { 
     userChoice = prompt("Choose a number between 1 - 100", "It must be a whole number!"); 
    } 
}; 

var randNumber = Math.floor(Math.random() * 100 + 1); 
var userChoice = prompt("Choose a number between 1 - 100"); 
console.log(userChoice); 
check(userChoice); 
//Above sorts out the computer choice and sets the rules for the user choice 

while(userChoice != randNumber) { 
    if (userChoice > randNumber) { 
     userChoice = prompt("Your number is GREATER than the computer.", "Please re-choose a number between 1 - 100"); 
     check(userChoice); 
    } 
    else if (userChoice < randNumber) { 
     userChoice = prompt("Your number is SMALLER than the computer.", "Please re-choose a number between 1 - 100"); 
     check(userChoice); 
    } 
}  

console.log("Your number matches! Congratulations!"); 

Это модификация какого-то более раннего кода, который у меня был, который чаще всего падал бы. Хотя приведенный выше код более стабилен, он по-прежнему периодически падает, хотя я не могу объяснить точную процедуру инициализации цикла infinte.

старый код выглядит следующим образом: (в качестве приоритета может кто-то говорит мне, почему это происходит сбой, я не вижу, почему цикл, пока не заканчивается, когда правильное число будет достигнуто?!)

main = function() { 


var randNumber = Math.floor(Math.random() * 100 + 1); 
var userChoice = prompt("Choose a number between 1 - 100"); 
while ((isNaN(userChoice)) || (userChoice > 100) || (userChoice < 1) || (userChoice %1 !== 0)) { 
    userChoice = prompt("Choose a number between 1 - 100", "It must be a whole number!"); 
} 
//Above sorts out the computer choice and sets the rules for the user choice 

while(userChoice !== randNumber) { 
    if (userChoice > randNumber) { 
     userChoice = prompt("Your number is GREATER than the computer.", "Please re-choose a number between 1 - 100"); 
    } 
    else if (userChoice < randNumber) { 
     userChoice = prompt("Your number is SMALLER than the computer.", "Please re-choose a number between 1 - 100"); 
    } 
}  

return("Your number matches! Congratulations!"); 

}; 
main(); 
+0

, кажется, работает хорошо для меня. Когда вы замечаете бесконечный цикл? – MitulP91

+0

@ MitulP91 Ну это кажется довольно странным. Я просто приступил к сбою снова, неоднократно помещая случайные числа, минус числа, буквы и символы. Я не думаю, что это может привести к сбою, если вы перегрузите браузер? Я очень новичок в этом, поэтому я могу просто быть идиотом! – JoeTea

+2

Самым умным было бы сбросить этот код в стиле 1995 года. Напишите документ с текстовым вводом, кнопкой и местом для вывода ваших сообщений. Ваш скрипт будет оценивать значение ввода, когда пользователь нажимает кнопку. Пользователи HATE запрашивают, и они ** действительно ** ненавидят, что они появляются снова и снова. –

ответ

1

вопрос с «старым кодом» является то, что вы используете «строгое равенство Сравнение» !== в while условия, что не будет удовлетворяться если вы не нажмете userChoice на число, поскольку приглашение возвращает строковое значение. Он будет работать, если вместо этого вы используете !=.

Проблема с «новым кодом» имеет дело с закрытием, внутри функции check новая локальная переменная userChoice создается потому, что вы передаете аргумент, что означает, что userChoice внутри чека не то же самое, что вы userChoice объявленная вне, вы можете просто удалить параметр и использовать глобальную переменную, которую вы определили:

var check = function() {...} 
... 
var userChoice = prompt("Choose a number between 1 - 100"); 
check(); 
+0

Это очень четкое и полезное объяснение обоих вопросов, спасибо вам большое! – JoeTea

0

Ваша проблема является:

while(userChoice !== randNumber) { 

результат userChoice (результат prompt) является строкой и randNumber это число.

Так что если randNumber является 1, и пользователь вводит 1, результат по-прежнему является строкой.
Таким образом, сравнение 1 !== "1", которое является true.

Из-за этого у вас всегда будет бесконечный цикл. (В строке всегда !==).

Вы можете изменить его к этому:

while(userChoice != randNumber) { 
0

Условием

(userChoice !== randNumber) 

никогда не может быть ложным, потому что означает «Разные, но того же типа» и стремительных возвращает строку «==!» , а не число! Поэтому, как только вы правильно угадали число, цикл никогда не заканчивается. Он только сбой, как только вы нашли ответ, потому что перед этим запрос замедляет цикл.

Помещенный

while(userChoice != randNumber) 

и вам будет хорошо :)

Посмотрите на это немного более современной версии, тоже: http://jsfiddle.net/e6gYJ/13/

0

Я считаю, что это ваше использование = = vs.! =

Когда вы используете! ==, вы явно сопоставляете тип AND.

так

5 !== "5"; //will be true 
5 !== 5; //will be false 

тогда

5 != '5'; // will be false 
+0

Хахаха, боже, я не могу поверить, что все было так просто! Я еще больше удивляюсь, что я не думал попробовать! Спасибо :) – JoeTea

1

Я думаю, что мне удалось найти, почему код попадает в бесконечный цикл:

Первая:

var check = function(userChoice) { .... }; 

Внутри этой функции, вы делаете

userChoice = prompt("[...]"); 

This userChoice ссылается на аргумент userChoice функции. Таким образом, он не может изменить глобальный userChoice, который вы определяете ниже, потому что он представляет собой совершенно другую переменную.

Во-вторых, вы объявите ваш глобальный userChoice:

var userChoice = prompt("Choose a number between 1 - 100"); 

Это создает в глобальной области видимости переменной userChoice и назначается независимо пользователь вводит в строке. Это может быть строка!

Затем выполнить вашу проверку функции: check(userChoice);

Проходите глобальный userChoice в качестве аргумента, но внутри вашей функции, userChoice ссылки местного userChoice, а не глобальный.

После ввода целого значения не больше, чем 100 и не меньше, чем 1, в то время как выходит ...

В это время, глобальная userChoice еще значение, введенное в первую очередь потому, что вы манипулировать другой переменной (локальной).

Затем вы выполняете следующее, в то время как с введенным вами значением в первую очередь. Если это значение не удовлетворяет userChoice !== randNumber, он входит в цикл; если userChoice > randNumber или userChoice < randNumber.

Если вы ввели строку, эти три проверки терпят неудачу. Таким образом, создается бесконечный цикл.

Т.Л., др - Как это исправить

Удалить аргумент вашей проверки функции, так что вы не создать локальную переменную:

function check() { 
    while ((isNaN(userChoice)) || (userChoice > 100) || (userChoice < 1) || (userChoice %1 !== 0)) { 
     userChoice = prompt("Choose a number between 1 - 100", "It must be a whole number!"); 
    } 
}; 
+0

Спасибо, это очень ясно и очень полезно! – JoeTea

+0

Я отправил вопрос, как за полчаса до вас ... –

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