【问题标题】:Javascript: why does random number generation not use new seed value in each for loop iteration?Javascript:为什么随机数生成不在每次 for 循环迭代中使用新的种子值?
【发布时间】:2020-08-31 04:10:34
【问题描述】:

我很困惑为什么下面通过 for 循环在每次迭代中为种族和性别生成相同的值对。我会想象 random() 的初始种子值(未在我的代码中明确声明)是在第一次迭代中获取的,然后循环根据初始种子继续到随机序列中的下一个值,但似乎不是案子。相反,它似乎在每次迭代中使用相同的种子/值,从而在每次迭代中产生相同的种族和性别值。

最小的工作示例:

    // Two arrays
    var race = ["B","W"];
    var gender = ["F", "M"];	
    
    for (i = 0; i < 6; i++) {
            var race = race[Math.floor(Math.random()*race.length)];
            var gender =  gender[Math.floor(Math.random()*gender.length)];
            document.write(race)
            document.write(gender)
            } 

    // Example result: BMBMBMBMBMBM (BM repeated 6 times)

是否有某种方式循环使用独立绘制的值,而不是为每个循环迭代生成相同的值?显然,C++ 已经回答了这个问题,Javascript seeding 有很多问题,但不是这个。

【问题讨论】:

  • 在代码 sn-p 中,您对数组和随机生成的变量都使用了“race”和“gender”。您需要使用 4 个不同的名称。

标签: javascript loops random


【解决方案1】:

在代码 sn-p 中,您对数组和随机生成的变量都使用了“race”和“gender”。您需要使用 4 个不同的名称。

    // Two arrays
    var races = ["B","W"];
    var genders = ["F", "M"];	
    
    for (i = 0; i < 6; i++) {
            var race = races[Math.floor(Math.random()*races.length)];
            var gender =  genders[Math.floor(Math.random()*genders.length)];
            document.write(race)
            document.write(gender)
            } 

    // Example result: BMBMBMBMBMBM (BM repeated 6 times)

如果您使用了“const”和“let”,您会收到一条错误消息。

    // Two arrays
    const race = ["B","W"];
    const gender = ["F", "M"];	
    
    for (i = 0; i < 6; i++) {
            let race = race[Math.floor(Math.random()*race.length)];
            let gender =  gender[Math.floor(Math.random()*gender.length)];
            document.write(race)
            document.write(gender)
            } 

【讨论】:

  • 可能还会提到为什么在使用letconst 时不会出现此类问题
  • 请注意,我接受此作为最直接回答问题的答案,但@user120242 的回答对于提升的技术解释更有帮助。
  • @user3614648 这实际上是我的意图,这就是为什么我忽略了其他答案中已经存在的实际答案
  • @user3614648 查看我的可运行 sn-p 示例以了解这一点,并查看 console.log 的输出。我也把cmets放在代码里解释一下。第二次迭代作用于字符串 "M"[(length=1 所以它总是 0)]
  • @user3614648 啊我明白你的困惑。 console.log 的输出使它看起来像是一个值。我已对其进行了更改,因此您可以再次查看以了解发生了什么。还记得第一次迭代是将两个数组强制转换为字符串
【解决方案2】:

看看你的变量名——你重用racegender作为数组,然后给它们赋值。做了一个快速的模型:

const race = ["B","W"];
const gender = ["F", "M"];    

for (i = 0; i < 6; i++) {
  let rand1 = Math.random();
  let rand2 = Math.random();
  console.log(`Random 1: ${rand1}, Random 2: ${rand2}`);
  let r = race[Math.floor(rand1*race.length)];
  let g =  gender[Math.floor(rand2*gender.length)];
  console.log(`Race: ${r}, Gender: ${g}`);
}

【讨论】:

  • 谢谢!估计脑子没电了奇怪的是,这会在第一个和最后一个元素不是 ["B","W"] 的循环中产生 console.log(race) 吗?
【解决方案3】:

由于提升,Javascript 会将 var 声明移动到作用域上下文的顶部。
https://www.w3schools.com/js/js_hoisting.asp
要获得更准确的描述,您可以阅读此内容,但上述描述在概念上更易于理解:https://developer.mozilla.org/en-US/docs/Glossary/Hoisting

你的代码实际上是这样结束的:

// Two arrays
var race = ["B","W"];
var gender = ["F", "M"];    

for (i = 0; i < 6; i++) {
        race = race[Math.floor(Math.random()*race.length)];
        gender =  gender[Math.floor(Math.random()*gender.length)];
        document.write(race)
        document.write(gender)
        } 

// Example result: BMBMBMBMBMBM (BM repeated 6 times)

我在下面的代码中插入了一个 console.log,以显示正在发生的事情:

// Two arrays
    var race = ["B","W"];
    var gender = ["F", "M"];	
    
    for (i = 0; i < 6; i++) {
// note that after the first loop, you are actually just using the string
// the race[] is actually just taking 1 character from race, or ie ("M F")[0]
console.log("race=",race,"gender=",gender);
            var race = race[Math.floor(Math.random()*race.length)];
            var gender =  gender[Math.floor(Math.random()*gender.length)];
            document.write(race)
            document.write(gender)
            } 

    // Example result: BMBMBMBMBMBM (BM repeated 6 times)

通常建议最佳做法是使用 let 和 const 代替 var 以避免引入此类错误,因为 let 和 const 不会被提升,并且不鼓励以可能导致此类意外行为的方式重用变量。

【讨论】:

  • 这样更清楚。所以只需使用race2 或gender2 之类的东西,gender2 和race2 的输出就是我想要的。
  • 是的,所以使用单独的变量会给你想要的。
猜你喜欢
  • 1970-01-01
  • 2020-08-05
  • 2014-01-05
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 2011-05-06
  • 2012-11-07
相关资源
最近更新 更多