如何解决不使用eval的JavaScript字符串计算器的运算符异常问题
JavaScript计算器问题修复方案
问题根因
hatatespit函数未生效原因:- 循环条件错误:
_error.includes(str)仅判断整个字符串完全匹配错误运算符组合,正常带数字的表达式永远无法进入循环 - 替换逻辑错误:所有替换操作都基于原始
str执行,未更新str的值,多次替换结果会相互覆盖 - 未调用处理函数:主逻辑中没有调用
hatatespit,处理结果从未传入计算流程
- 循环条件错误:
- 首位为运算符返回NaN原因:你的栈计算逻辑默认所有运算符均为二元运算符,需要两个操作数参与计算,首位的
+/-属于一元运算符,前面缺少默认操作数0,导致计算时取到undefined,转数字后为NaN
修复步骤
- 修复
hatatespit函数,循环替换所有连续错误运算符直到无匹配项 - 新增首位运算符兼容逻辑:首位为
+/-时自动补0,首位为*//时抛出非法输入错误 - 主流程中先执行预处理逻辑,再将处理后的字符串传入计算函数
修复后完整代码
// 修复后的连续运算符处理函数 const hatatespit = (str) => { const _error = ['--','+-','//','**','-+','++']; // 循环检查是否存在错误组合,存在就替换 while (_error.some(item => str.includes(item))) { str = str.replace('--','+'); str = str.replace('-+','-'); str = str.replace('+-','-'); str = str.replace('//','/'); str = str.replace('**','*'); str = str.replace('++','+'); } return str; }; const calcute = str => { const deger = []; const operator = []; const Numbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."]; for (let i = 0; i < str.length; i++) { if (Numbers.includes(str[i])) { let arabellek = ""; while (i < str.length && Numbers.includes(str[i])) { arabellek += str[i]; i++; } deger.push(parseFloat(arabellek)); i--; } else if (str[i] === '(') { operator.push(str[i]); } else if (str[i] === ')') { while (operator[operator.length - 1] !== '(') { deger.push(hesapla(operator.pop(), deger.pop(), deger.pop())); } operator.pop(); } else if (str[i] === '+' || str[i] === '-' || str[i] === '*' || str[i] === '/') { while (operator.length && islemOnceligi(str[i], operator[operator.length - 1])) { deger.push(hesapla(operator.pop(), deger.pop(), deger.pop())); } operator.push(str[i]); } } while (operator.length) { deger.push(hesapla(operator.pop(), deger.pop(), deger.pop())); } return deger.pop(); }; const islemOnceligi = (op1, op2) => { if (op2 === '(' || op2 == ')') { return false; } if ((op1 === '*' || op1 === '/') && (op2 === '+' || op2 === '-')) { return false; } return true; }; const hesapla = (op, y, x) => { switch (op) { case '+': return parseFloat(x + y); case '-': return parseFloat(x - y); case '*': return parseFloat(x * y); case '/': if (y === 0) { throw 'Sıfıra bölüm hatası!'; } return parseFloat(x / y); } return 0; }; // 主逻辑新增预处理步骤 var cumle = prompt("HESAPLAMAK İSTEDİNİZ İSLEMİ GİRİN"); try { // 处理首位运算符 if (/^[\+\-]/.test(cumle)) { cumle = '0' + cumle; } if (/^[\*\/]/.test(cumle)) { throw '表达式首位不能为乘除运算符'; } // 处理连续运算符 cumle = hatatespit(cumle); // 计算并输出 document.write(calcute(cumle)); } catch (e) { document.write('错误:' + e); }
<h2>CALCULATOR</h2>
验证效果
- 输入
+10-5:预处理为0+10-5,输出结果5 - 输入
-10/5:预处理为0-10/5,输出结果-2 - 输入
10-+5:处理为10-5,输出结果5 - 输入
10++55:处理为10+55,输出结果65
内容的提问来源于stack exchange,提问作者birsivasefsanesi
相关产品推荐
相关产品推荐

