JavaScript - 在for循环中使用Math.random

5

我在尝试在Javascript中使用for循环的条件中生成随机数时,发现了一些有趣的东西。

如果我像这样编写代码:

for (var i = 0; i < 20; i++) {
    var count = 0;
    for (var j = 0; j < Math.floor(Math.random() * 20); j++) {
        count++;
    }
    console.log(count);
}

它将返回以下结果:
9
5
8
3
3
2
6
8
4
4
5
6
3
3
5
3
4
5
3
11

但是如果我在第二个for循环之前生成一个随机数变量:
for (var i = 0; i < 20; i++) {
    var count = 0;
    var loopEnd = Math.floor(Math.random() * 20 + 1);
    for (var j = 0; j < loopEnd; j++) {
        count++;
    }
    console.log(count);
}

它会返回像这样的结果:

11
13
14
2
19
19
17
19
2
18
5
15
18
2
1
19
16
15
13
20

这里到底发生了什么?我有点困惑。for循环中的Math.random()是在每次迭代后生成一个新的随机数吗?循环运行代码、迭代、检查条件,每次检查条件时都会生成一个新的随机数吗?这就是正在发生的事情,这就是为什么控制台中的数字比在for循环之前使用Math.random()赋值给变量要小的原因吗?


2
j < Math.floor(Math.random() * 20)会在每次迭代中运行,并且每次都具有不同的随机值...所以,当然你很快就会得到false结果。 - Jaromanda X
1
是的,在每次迭代之前都会重新评估循环终止条件(包括它所做的任何函数调用)。 - Thilo
2个回答

8
在第一个示例的内部循环中:
...
for (var j = 0; j < Math.floor(Math.random() * 20); j++) {
    count++;
}
...

循环的终止条件j < Math.floor(Math.random() * 20)在每次迭代中都会被评估,因此终止值会随着对Math.random()的调用而在每次迭代中改变,从而更有可能使循环提前终止。


哇,我已经使用JavaScript多年了,最近遇到了这个问题。知道这个真是太好了! - Jose A

2
关于每次迭代选择新的随机数时循环提前终止的问题:
不涉及正式的统计分析,考虑这个简单的思路:
你有多大可能得到十次或更多次迭代?
如果你只抽一次1到20之间的随机数,你将有50%的概率得到10次或者更多次。
如果你得到了十个随机数,你需要让它们每一个都比第一个数更高,然后是第二个数,第三个数等等,这样的概率就会降低:95% * 90% * 85% * ... * 50%。

1
这是一个很好的观点。从统计学的角度来看,很有趣。谢谢! - Sam McLennan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接