JavaScript:如何在Fisher-Yates循环中向空数组写入值并显示?
问题排查与修复方案
代码中的核心错误
未定义变量引用
初始代码中document.getElementById("demo").innerHTML = arsam2;里的arsam2从未声明,应该改为arsam1。局部变量重复声明导致数组无法赋值
在myFunction的循环里,使用let iValue1[i] = i;和let jValue1[i] = j;是错误的:- 你已经在全局作用域声明了
iValue1和jValue1,这里加let会创建同名局部变量,导致全局数组无法被修改 - 正确的做法是直接使用全局数组的赋值方法,比如
iValue1.push(i)(推荐用push更符合数组操作逻辑)
- 你已经在全局作用域声明了
DOM更新时机错误
更新iValue和jValue元素内容的代码写在全局作用域,只会在页面加载时执行一次,点击按钮后不会触发更新。必须把这些DOM操作放到myFunction内部,确保点击后实时更新页面。数组未重置导致多次点击数据累加
每次点击按钮执行Fisher-Yates排序时,iValue1和jValue1会保留之前的数据,需要在函数开头清空数组。
修正后的完整代码
JavaScript部分
const arsam1 = [5, 10, 15, 18, 6, 3, 9, 23, 29, 17, 12, 40]; let iValue1 = []; let jValue1 = []; // 初始化显示原始数组 document.getElementById("demo").innerHTML = arsam1; function myFunction() { // 重置存储数组,避免多次点击累加 iValue1 = []; jValue1 = []; // 复制原数组进行排序,避免修改原始数组(可选,根据需求调整) const sortedArray = [...arsam1]; for (let i = sortedArray.length - 1; i > 0; i--) { // 存储循环变量i和随机索引j iValue1.push(i); let j = Math.floor(Math.random() * (i + 1)); jValue1.push(j); // Fisher-Yates交换逻辑 [sortedArray[i], sortedArray[j]] = [sortedArray[j], sortedArray[i]]; } // 更新页面内容 document.getElementById("demo").innerHTML = sortedArray; document.getElementById("iValue").innerHTML = `循环变量i的值:${iValue1.join(', ')}`; document.getElementById("jValue").innerHTML = `随机索引j的值:${jValue1.join(', ')}`; }
HTML部分
<h1>Fisher-Yates排序过程展示</h1> <p>点击按钮查看随机排序的过程细节</p> <p id="demo"></p> <button onclick="myFunction()">Randomize</button> <p id="iValue"></p> <p id="jValue"></p>
额外优化说明
- 新增数组复制逻辑
const sortedArray = [...arsam1];,避免每次点击修改原始数组,方便对比原始数据和排序结果 - 使用数组解构
[sortedArray[i], sortedArray[j]] = [sortedArray[j], sortedArray[i]]简化交换代码,可读性更强 - 给显示内容添加描述文本,让页面展示更清晰
内容的提问来源于stack exchange,提问作者Adam Givon
相关产品推荐
相关产品推荐

