如何基于Luhn算法实现信用卡校验器?现有代码求和返回NaN如何修复?
问题原因与修复方案
核心bug导致NaN的原因
multipliedString变量没有初始值,默认是undefined,第一次执行拼接操作undefined + 数字时就会得到NaN字符串,后续所有计算都会出错- 处理大于9的乘积时,你把数字类型的
multipliedNumber直接用索引[0]/[1]取位,数字类型没有字符串的索引属性,这一步返回undefined,相加后也会得到NaN - 额外兼容问题:你的输入框用了
type="number",如果用户按照占位符提示输入带空格的16位卡号,输入框的value会直接返回空值,导致长度校验不通过
修正后的完整代码
HTML部分
<input type="text" id="creditCard" placeholder="0000 0000 0000 0000"> <input type="submit" id="checkButton" value="CHECK VALIDITY" onclick="checkNumber()">
JS部分
function checkNumber() { // 先移除所有非数字字符,兼容带空格/分隔符的输入格式 let number = document.getElementById("creditCard").value.replace(/\D/g, ''); let multiplier = "212121212121212"; let multipliedString = ""; // 初始化空字符串,避免undefined拼接 if (number.length != 16) { alert("请输入16位长度的信用卡号"); return; } for (let count = 0; count < number.length - 1; count++) { // 显式转数字避免隐式类型转换问题 let multipliedNumber = Number(number[count]) * Number(multiplier[count]); if (multipliedNumber > 9) { // 先转成字符串再取位,再转数字相加 let numStr = multipliedNumber.toString(); multipliedNumber = Number(numStr[0]) + Number(numStr[1]); } multipliedString += multipliedNumber; } // 单独做求和逻辑,避免长字符串转数字的精度问题 let total = 0; for (let char of multipliedString) { total += Number(char); } // 额外加一层%10处理余数为0时校验位为0的边界情况 let checkDigit = (10 - (total % 10)) % 10; if (checkDigit == Number(number[15])) { alert(`${number} 是有效的信用卡号`); } else { alert(`${number} 不是有效的信用卡号`); } }
内容的提问来源于stack exchange,提问作者b07580
相关产品推荐
相关产品推荐

