为什么这段代码有时会使浏览器崩溃

Why does this code sometimes crash the browser?

本文关键字:浏览器 崩溃 段代码 代码 为什么      更新时间:2023-09-26

谁能向我解释为什么这段代码有时会进入无限循环(大概是从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!");

这是我对一些早期代码的修改,这些代码会更频繁地崩溃。尽管上面的代码更稳定,但它仍然偶尔会崩溃,尽管我无法解释启动无限循环的确切过程。

旧代码如下:(作为优先事项,有人可以告诉我为什么会崩溃吗?我不明白为什么当达到正确的数字时,while循环没有结束!

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

"旧代码"的问题在于,您在while条件中使用"严格相等比较"!==,除非您将 userChoice 转换为数字,否则不会满足该条件,因为提示返回字符串值。如果您改用!=,它将起作用。

"新代码"的问题与闭包有关,在check函数内部创建了一个新的局部变量userChoice因为你传递了一个参数,这意味着 userChoice inside check 与你在外面声明的userChoice不同,你可以删除参数并使用你定义的全局变量:

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

我想我已经设法找到了代码进入无限循环的原因:

第一:

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

在这个函数中,你正在做

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

userChoice引用函数的参数userChoice。因此,它无法更改您在下面定义的全局userChoice,因为它是一个非常不同的变量。

其次,您声明您的全局userChoice

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

这将在全局作用域中创建一个变量userChoice,并分配用户在提示中输入的任何内容。可能是一根绳子!!

然后,执行函数检查:check(userChoice);

您将全局userChoice作为参数传递,但在函数内部,userChoice引用本地userChoice而不是全局。

输入不大于 100 也不小于 1 的整数值后,while 将退出...

此时,全局userChoice仍然是您最初输入的值,因为您操作了另一个变量(局部变量)。

然后,使用您首先输入的值执行下一个while。如果此值不满足userChoice !== randNumber,则进入循环;检查是否userChoice > randNumberuserChoice < randNumber

如果输入字符串,则这三个检查将失败。因此,创建一个无限循环。

TL;dr - 如何解决此问题

删除检查函数的参数,这样就不会创建局部变量:

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!");
    }
};

你的问题是:

while(userChoice !== randNumber) {

userChoice的结果(prompt的结果)是一个字符串,randNumber是一个数字。

因此,如果randNumber 1并且用户输入1则结果仍然是字符串。
所以比较是1 !== "1" true.

正因为如此,你将永远有一个无限循环。(数字始终!==到字符串中)。

您可以将其更改为:

while(userChoice != randNumber) {
我相信

这是你对 !== 与 != 的用法

使用 !== 时,将显式匹配类型 AND 值。

所以

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

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

条件

(userChoice !== randNumber)

永远不能为假,因为"!=="表示"不同但类型相同",提示返回一个字符串,而不是一个数字!因此,一旦您猜对了数字,循环就永远不会结束。只有在找到答案后,它才会崩溃,因为在此之前,提示会减慢循环速度。

while(userChoice != randNumber)

你会没事的:)

看看这个稍微现代一点的版本:http://jsfiddle.net/e6gYJ/13/