随机数生成异常:调用startTurn函数始终返回相同3个数值
问题:每次调用startTurn函数都生成相同的3个数值
项目包含一个从basket数组中生成三个随机数并映射到按钮的函数,预期每次点击按钮都会得到三个新数值,且点击的数值会从数组中移除。但每次调用startTurn函数时,它都会输出相同的3个数值。
原代码
const repeat = (arr, n) => Array(n).fill(arr).flat(); let basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3); function newGame() { basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3); console.log(basket); startTurn(); } const button1 = document.querySelector('#button1'); const button2 = document.querySelector('#button2'); const button3 = document.querySelector('#button3'); const button4 = document.querySelector('#new-game'); let turncount = 0; let choice = []; function startTurn(){ while(choice.length <= 3){ let r = Math.floor(Math.random() * (basket.length)) ; if(choice.indexOf(r) === -1) choice.push(r); } button1.style.backgroundColor = basket[choice[0]]; button2.style.backgroundColor = basket[choice[1]]; button3.style.backgroundColor = basket[choice[2]]; console.log(basket.length); console.log(basket[choice]) }
问题原因
- 全局变量
choice未重置:choice是全局变量,第一次调用startTurn后就已经存入了3个索引值,后续调用时while(choice.length <= 3)的条件直接不成立,不会生成新的随机索引,一直复用旧值。 - 未实现元素移除逻辑:代码里只记录了索引,没有把选中的元素从
basket数组中移除,就算生成新索引,原数组内容没变化,也达不到“用过的数值不再出现”的效果。
修复方案
把choice改成startTurn的局部变量,每次调用都重新生成;同时每次选中元素后从basket中移除该元素,确保下次不会重复选中。
修复后的代码:
const repeat = (arr, n) => Array(n).fill(arr).flat(); let basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3); function newGame() { basket = repeat(["red", "orange", "yellow", "green", "blue", "purple"], 3); console.log(basket); startTurn(); } const button1 = document.querySelector('#button1'); const button2 = document.querySelector('#button2'); const button3 = document.querySelector('#button3'); const button4 = document.querySelector('#new-game'); let turncount = 0; function startTurn(){ // 把choice改为局部变量,每次调用都重新初始化 const choice = []; // 循环生成3个不重复的随机元素 while(choice.length < 3 && basket.length > 0){ const r = Math.floor(Math.random() * basket.length); // 取出对应元素并存入choice choice.push(basket[r]); // 从basket中移除已选中的元素 basket.splice(r, 1); } // 给按钮设置背景色 button1.style.backgroundColor = choice[0]; button2.style.backgroundColor = choice[1]; button3.style.backgroundColor = choice[2]; console.log(basket.length); console.log(choice); }
关键修改点
- 将
choice从全局变量改为startTurn内部的局部变量,确保每次调用函数都重新生成随机选择。 - 使用
splice(r, 1)从basket中移除已选中的元素,实现“用过的数值不再出现”的需求。 - 调整循环条件,同时判断
basket.length > 0,避免数组为空时继续循环。
内容的提问来源于stack exchange,提问作者Issac Alleyne
相关产品推荐
相关产品推荐

