JavaScript中空字符串/NaN判断分支未触发问题求助
乘法答题游戏空输入/非数字判断失效问题排查与修复
问题描述
开发乘法答题网页游戏时,需要处理用户空输入或非数字(NaN)的情况,但测试发现对应判断分支从未触发,导致平均得分统计错误。输入空字符串时parseFloat返回NaN,但代码中的else-if分支始终不执行。
核心原因
- 判断顺序逻辑错误:现有代码先判断
input !== getProduct(),当input为NaN时,NaN !== 任何值都会返回true,直接进入错误分支,永远到不了空/非数字判断的else-if。 - isNaN调用错误:
isNaN()未传入参数,默认判断undefined,永远返回false,无法检测输入是否为NaN。 - 无效的空字符串判断:
parseFloat("")返回NaN,所以input永远不会等于' ',该判断无意义。 - 统计逻辑错误:空/非数字输入被计入错误次数和总次数,导致平均得分被错误拉低。
修复方案
- 调整判断顺序:优先判断输入是否为NaN,再处理正确/错误情况。
- 修正
isNaN调用,传入input参数。 - 移除无效的
input === ' '判断。 - 空/非数字输入时不更新错误次数和总次数,避免影响统计。
修正后的关键代码
修改后的evaluateAnswer函数
function evaluateAnswer(input) { console.log('Input value on eval ', input); // 先判断是否为非数字(空输入parseFloat后也是NaN) if (isNaN(input)) { console.log('Input value is empty or not a number ', input); // 空输入不统计次数,不修改得分 } else if (input === getProduct()) { addPoint(); correctGuesses++; totalGuesses++; } else { subtractPoint(); incorrectGuess++; totalGuesses++; } restartGame(); guessP.textContent = "Incorrect Guesses= " + incorrectGuess; // 处理总次数为0的情况,避免除以0报错 let average = totalGuesses === 0 ? 0 : (correctGuesses / totalGuesses); let precisionAvg = roundToPrecision(average, 2); averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`; }
补充说明
- 新增总次数为0的判断,避免页面初始化或无有效输入时出现除以0的错误。
- 空/非数字输入不再计入
totalGuesses,保证平均得分统计仅针对有效答题。
完整修正后的JavaScript代码
const equationTag = document.querySelector('div#equation'); const inputBtn = document.querySelector('input.submit-btn'); const incorrectTag = document.querySelector('p#incorrect'); const correctTag = document.querySelector('p#correct'); const counterTag = document.querySelector('div#counter'); const exitButton = document.querySelector('button.exit-btn'); const displayButton = document.querySelector('button.display-btn'); const resultModal = document.querySelector('section.stats-section'); const averageP = document.querySelector('p.avg'); const guessP = document.querySelector('p.total-guesses'); let points = 0; let correctGuesses = 0; let incorrectGuess = 0; let totalGuesses = 0; function getRandomValue(min, max) { let r = Math.floor(Math.random() * (max - min + 1)) + min; return r; } function displayEquation() { equationTag.textContent = `${integerOne} x ${integerTwo}=`; } function getProduct() { return integerOne * integerTwo; } inputBtn.addEventListener('click', () => { const inputTag = document.querySelector('#num'); const answer = parseFloat(inputTag.value); evaluateAnswer(answer); inputTag.value = ""; inputTag.focus(); }) document.addEventListener("keydown", (event) => { if (event.key === "Enter") { const inputTag = document.querySelector('#num'); const answer = parseFloat(inputTag.value); evaluateAnswer(answer); inputTag.value = ""; inputTag.focus(); } }) exitButton.addEventListener('click', () => { setDisplayNone(resultModal); }) displayButton.addEventListener('click', () => { setDisplayBlock(resultModal); }) function evaluateAnswer(input) { console.log('Input value on eval ', input); if (isNaN(input)) { console.log('Input value is empty or not a number ', input); } else if (input === getProduct()) { addPoint(); correctGuesses++; totalGuesses++; } else { subtractPoint(); incorrectGuess++; totalGuesses++; } restartGame(); guessP.textContent = "Incorrect Guesses= " + incorrectGuess; let average = totalGuesses === 0 ? 0 : (correctGuesses / totalGuesses); let precisionAvg = roundToPrecision(average, 2); averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`; } function subtractPoint() { if (points <= 0) { points = 0; } else { points -= 1; } setDisplayBlock(incorrectTag); setDisplayNone(correctTag); incorrectTag.textContent = ('Incorrect: ' + integerOne + ' x ' + integerTwo + ' = ' + getProduct()); setPoint(); } function setPoint() { counterTag.textContent = points; } function addPoint() { points += 1; correctTag.textContent = ('Correct!'); setDisplayBlock(correctTag); setDisplayNone(incorrectTag); setPoint(); } function restartGame() { integerOne = getRandomValue(0, 12); integerTwo = getRandomValue(0, 12); displayEquation(); } function setDisplayBlock(displayResult) { displayResult.style.display = 'block'; displayResult.style.opacity = 1; } function setDisplayNone(displayResult) { displayResult.style.display = 'none'; displayResult.style.opacity = 0; } function roundToPrecision(value, decimals = 2) { const pow = Math.pow(10, decimals); return Math.round((value + Number.EPSILON) * pow) / pow; } let integerOne = getRandomValue(0, 12); let integerTwo = getRandomValue(0, 12); displayEquation();
内容的提问来源于stack exchange,提问作者rojey12
相关产品推荐
相关产品推荐

