通过prompt调用函数实现JavaScript计算器的问题排查
无switch/ifelse的简易计算器问题排查与修复
我正在编程训练营做一个简易计算器,要求通过prompt指定调用对应运算函数,不想用switch/ifelse,但当前代码无法输出预期结果(比如输入2、3、add后,期望控制台显示“2 + 3 = 5”),请帮忙排查问题,原代码如下:
/*You will need to create four functions: ● add — This function will add the two numbers together. ● subtract — This function will subtract the second number from the first number. ● multiply — This function will multiply the two numbers together. ● divide — This function will divide the first number by the second number. ● Your calculator should ask the user to input the first number, the second number and what operation they would like to perform on those numbers. ● The program should then log the calculation and the total to the console. For example if the user inputs 6, 7 and multiply, the output would be: 6 x 7 = 42*/ //get n1, n2 let n1 = ((Number(prompt("Input your first number")))); let n2 = ((Number(prompt("Input your second number")))); let task =((Function(prompt ("Should I add, subtract, multiply or divide? (lowecase please!)")))); var sym = (""); function add (n1, n2){ sym = ("+"); return n1+n2; } function subtract (n1, n2){ sym = ("-"); return n1-n2; } function multiply (n1, n2){ sym = ("x"); return n1*n2; } function divide (n1, n2){ sym = ("/"); return n1/n2; } console.log (`${n1} ${sym} ${n2} = ${task(n1,n2)}`);
问题1:函数获取方式错误
你用Function(prompt(...))来获取运算函数是完全错误的。Function构造函数需要传入函数体字符串(比如"return n1+n2"),但用户输入的是函数名(比如"add"),这会导致创建的task是一个无意义的空函数,调用时要么返回undefined,要么直接报错。
问题2:符号变量sym的时机问题
console.log执行时,sym还是初始的空字符串——因为task(n1,n2)是在模板字符串里才调用,此时sym的赋值是在函数内部,虽然调用后会改,但模板字符串里的sym已经先被解析了,所以输出里的符号会是空的。而且用全局变量存符号也不是好的写法。
修复方案
用对象映射的方式把操作名和对应的运算函数、符号绑定在一起,既不用switch/ifelse,又能正确获取函数和符号:
修复后的代码:
// 定义运算函数 function add(n1, n2) { return n1 + n2; } function subtract(n1, n2) { return n1 - n2; } function multiply(n1, n2) { return n1 * n2; } function divide(n1, n2) { // 简单处理除数为0的情况 if (n2 === 0) return "不能除以0"; return n1 / n2; } // 创建操作映射:键是用户输入的操作名,值是包含函数和符号的对象 const operations = { add: { func: add, symbol: "+" }, subtract: { func: subtract, symbol: "-" }, multiply: { func: multiply, symbol: "x" }, divide: { func: divide, symbol: "/" } }; // 获取用户输入 let n1 = Number(prompt("输入第一个数字")); let n2 = Number(prompt("输入第二个数字")); let taskName = prompt("选择运算:add/subtract/multiply/divide(小写)"); // 获取对应的操作配置 const selectedOp = operations[taskName]; // 验证输入的操作是否有效 if (!selectedOp) { console.log("无效的操作类型"); } else { const result = selectedOp.func(n1, n2); console.log(`${n1} ${selectedOp.symbol} ${n2} = ${result}`); }
修复说明
- 用
operations对象把操作名和对应的函数、符号关联起来,直接通过用户输入的taskName就能拿到对应的配置,完全不需要switch/ifelse。 - 先获取操作配置,再调用函数计算结果,最后输出时直接用配置里的符号,避免了全局变量的时机问题。
- 增加了无效操作的判断,提升了代码健壮性。
- 优化了除数为0的异常处理(可选)。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

