
本文介绍如何在 JavaScript MCQ 应用中,从完整的题库数组中无重复、随机选取固定数量(如 5 道)题目进行展示,避免全部题目依次呈现,提升测验灵活性与公平性。
本文介绍如何在 javascript mcq 应用中,从完整的题库数组中**无重复、随机选取固定数量(如 5 道)题目**进行展示,避免全部题目依次呈现,提升测验灵活性与公平性。
要在现有 MCQ 应用中实现“仅展示 5 道随机题目”,关键在于:不直接遍历原始 quizData 全量数组,而是预先从中随机抽样生成一个长度为 5 的新题目子集,后续所有逻辑(加载、计分、翻页)均基于该子集运行。
推荐使用「Fisher-Yates 洗牌 + 截取」方案——既保证随机性,又避免重复索引或低效的 splice 循环。以下是完整改造步骤:
✅ 第一步:生成随机题目子集(5 道)
在定义 quizData 后、初始化逻辑前,添加如下代码:
// 从 quizData 中随机抽取 5 道题(不修改原数组)
const selectedQuizData = shuffleArray([...quizData]).slice(0, 5);
// Fisher-Yates 洗牌算法(高效、均匀、原地打乱)
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]]];
}
return array;
}? 为什么不用
Math.random()直接索引 +Set去重?
因为当题库较大而抽取数较小时效率尚可,但本例中题库仅 8 道,抽 5 道时重复概率显著升高;而洗牌法时间复杂度稳定为 O(n),且结果绝对无序、无偏。
✅ 第二步:替换全局变量与逻辑引用
将原代码中所有对 quizData 的直接引用,改为指向新数组 selectedQuizData:
let currentQuiz = 0;
let score = 0;
// ? 修改此处:使用抽样后的题库
const quizData = selectedQuizData; // ← 覆盖原变量名(保持后续代码零改动)
loadQuiz();
function loadQuiz() {
deselectAnswers();
const currentQuizData = quizData[currentQuiz]; // ✅ 自动生效
questionEl.innerText = currentQuizData.question;
a_text.innerText = currentQuizData.a;
b_text.innerText = currentQuizData.b;
c_text.innerText = currentQuizData.c;
d_text.innerText = currentQuizData.d;
}
// 提交逻辑中,判断结束条件也自动适配新长度:
submitBtn.addEventListener("click", () => {
const answer = getSelected();
if (answer) {
if (answer === quizData[currentQuiz].correct) score++;
currentQuiz++;
// ? 改为 quizData.length(即 5),而非硬编码或原数组长度
if (currentQuiz < quizData.length) {
loadQuiz();
} else {
quiz.innerHTML = `
<h2>You answered correctly at ${score}/${quizData.length} questions.</h2>
<button onclick="location.reload()">Reload</button>
`;
}
}
});⚠️ 注意事项
-
不要在
loadQuiz()中动态重抽题:否则每次翻页都会重新随机,导致题目重复或跳过; -
确保 DOM 元素存在:
#quiz,.answer,#question等 ID/类名需与 HTML 严格一致; - 兼容性友好:所用语法(解构赋值、可选链等)均兼容现代浏览器,无需额外转译;
-
扩展性强:只需修改
slice(0, 5)中的5,即可轻松切换为 3 题、10 题等任意数量。
通过以上改造,你的 MCQ 应用即可每次刷新都呈现一组全新的 5 道随机题目,在保持原有交互逻辑不变的前提下,显著提升用户体验与评估科学性。


















