JavaScript如何向函数传值 解决计算返回NaN的问题
问题原因
计算始终返回NaN是4处代码错误共同导致的:
- 变量作用域错误:
factor是在sel的change事件回调内部用var声明的局部变量,回调外的calculate函数无法访问到这个值,实际拿到的factor是undefined,和数字做运算必然返回NaN。且switch块内重复用var声明factor属于冗余无效写法。 - 形参被覆盖:
calculate定义了形参pfactor,但函数内部又重新声明同名变量指向DOM元素,传入的参数会被直接覆盖,且你从未在调用函数时给这个形参传值。 - 类型缺失转换:通过
.value拿到的表单值默认是字符串类型,虽然乘法存在隐式类型转换,但值为空或非数字时会直接触发NaN,需要手动转成数值类型。 - 事件未绑定逻辑:
psel的change事件绑定的是空函数,选中项变更时根本没有执行calculate逻辑。
修复方案
按以下顺序调整代码即可:
- 把
factor声明移到所有函数外层作为共享变量,去掉函数内部、switch块内重复的var factor声明,只保留对应分支的赋值逻辑 - 删掉
calculate内部重复声明pfactor的代码,避免覆盖传入的参数;计算时优先使用传入的参数值,同时把页数输入值转成整数,空值时默认按0计算避免NaN - 给
psel的change回调补充执行逻辑,触发时把当前最新的factor值作为参数传入calculate执行计算 - 可选优化:计算完成后给金额保留两位小数,展示格式更符合常规价格规范
修正后可运行代码
// 把factor提为外层共享变量,初始值设为默认档位1.0 let factor = 1.0; // 第一个天数选择下拉框逻辑 sel.addEventListener("change", function (evt) { // 直接拿选中值转整数即可,不需要通过options索引取值 const days = parseInt(evt.target.value); switch (days) { case 3: case 4: factor = 1.5; break; case 5: case 6: factor = 1.4; break; case 7: case 8: case 9: factor = 1.3; break; case 10: case 11: case 12: case 13: case 14: factor = 1.2; break; case 15: default: factor = 1.0; } // 如果需要选完天数立刻刷新计算结果,可在这里直接调用 calculate(factor) }); /** * 计算函数 * @param {number} pfactor 价格系数 */ function calculate(pfactor) { const nopages = document.getElementById("pages"); const priceOutput = document.getElementById("nopagesOutput"); // 转成整数,空值/非法值默认按0计算 const pageCount = parseInt(nopages.value) || 0; priceOutput.innerHTML = pageCount; const total = pageCount * 10 * pfactor; // 保留两位小数展示价格 document.getElementById("savings").innerHTML = `$ ${total.toFixed(2)}`; } // 第二个下拉框绑定变更事件,触发计算时传入最新的factor值 psel.addEventListener("change", function (evt) { calculate(factor); });
可选优化:如果不想使用外层共享变量,也可以在
calculate函数内部直接读取第一个下拉框的选中值,实时计算当前对应的factor,能避免全局变量污染问题。
内容的提问来源于stack exchange,提问作者somearabguy
相关产品推荐
相关产品推荐

