Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中计算字符串值,不使用eval_Javascript_Eval - Fatal编程技术网

在javascript中计算字符串值,不使用eval

在javascript中计算字符串值,不使用eval,javascript,eval,Javascript,Eval,有没有一种方法可以在不使用eval的情况下计算存储在JavaScript字符串中的公式 通常我会这样做 var apa = "12/5*9+9.4*2"; alert(eval(apa)); 那么,有人知道eval的替代方法吗?如果不想使用eval,则必须使用现有的表达式计算器库 你也可以自己滚动一个:)你不能,最多你可以做一些反驳的事情,比如解析数字,然后用开关将操作分开,并使它们。除此之外,我会在这种情况下使用eval 这将是一种(实际的实现会更复杂一些,特别是如果你考虑括号的使用,但

有没有一种方法可以在不使用
eval
的情况下计算存储在JavaScript字符串中的公式

通常我会这样做

var apa = "12/5*9+9.4*2";
alert(eval(apa));

那么,有人知道eval的替代方法吗?

如果不想使用eval,则必须使用现有的表达式计算器库


你也可以自己滚动一个:)

你不能,最多你可以做一些反驳的事情,比如解析数字,然后用开关将操作分开,并使它们。除此之外,我会在这种情况下使用eval

这将是一种(实际的实现会更复杂一些,特别是如果你考虑括号的使用,但是你知道了这个想法)


尽管如此,我认为最好的选择是使用eval,因为您可以信任字符串的来源。

这正是您应该使用eval的地方,否则您将不得不循环字符串并生成数字。您必须使用isNaN方法来执行此操作。

eval没有任何问题,尤其是对于这种情况。为了安全起见,可以先使用正则表达式清理字符串:

// strip anything other than digits, (), -+/* and .
var str = "12/5*9+9.4*2".replace(/[^-()\d/*+.]/g, '');
alert(eval(str));

Eval是在这样的条件下建造的

如果您想要另一种方法,您必须使用eval将要做的事情的纯Javascript实现

  • 难的部分不是解析数字和运算符
  • 难点在于应用操作顺序和递归控制
下面是我提出的一个快速的基本示例(更新版(2011-06-26):带输入框的清洁器)。

注意:

  • 它只处理基本运算符
  • 它不检查数字的有效性(例如:除以零)
  • 它没有实施附加手术
  • 基于以上种种原因,eval将是一个更好的选择
编辑(2017-05-26)以使用SO代码片段:

函数计算(输入){
变量f={
加:“+”,
sub:“-”,
分区:“/”,
mlt:“*”,
mod:'%1!',
exp:“^”
};
//为操作顺序和优先级创建数组
f、 ooo=[
[
[f.mlt],
[f.div],
[f.mod],
[f.exp]
],
[
[f.add],
[f.sub]
]
];
input=input.replace(/[^0-9%^*\/()\-+.]/g');//清除不必要的字符
var输出;
对于(变量i=0,n=f.ooo.length;i
标签{
显示:内联块;
宽度:4em;
}

方程式:
结果:

Mhh,您可以使用
函数
-构造函数:


下面是的一个实现,它还支持一元前缀(例如
-
)和后缀(例如
)运算符以及函数(例如
sqrt()
)符号。使用
计算可以轻松定义更多运算符/函数。defineOperator
方法:

“严格使用”;
阶级计算{
构造函数(){
这个。_符号={};
this.defineOperator(“!”,this.factorial,“postfix”,6);
这个.defineOperator(“^”,Math.pow,“infix”,5,true);
this.defineOperator(“*”,this.multiply,“infix”,4);
这个.定义运算符(“/”,这个.division,“infix”,4);
this.defineOperator(“+”,this.last,“prefix”,3);
this.defineOperator(“-”,this.negation,“prefix”,3);
this.defineOperator(“+”,this.addition,“infix”,2);
this.defineOperator(“-”,this.减法,“infix”,2);
这个.defineOperator(“,”,数组。的“中缀”,1);
this.defineOperator(“(”,this.last,“prefix”);
此.defineOperator(“)”,null,“后缀”);
这个.defineOperator(“min”,Math.min);
这个.defineOperator(“sqrt”,Math.sqrt);
}
//允许使用更多运算符和函数扩展实例的方法:
定义运算符(符号,f,notation=“func”,优先级=0,右至左=false){
//由符号/名称键入的存储运算符。某些符号可能表示
//不同的用法:例如“-”可以是一元或二元,因此它们也是
//按符号(前缀、中缀、后缀、func)键入:
如果(表示法==“func”)优先级为0;
this._symbols[symbol]=Object.assign({},this._symbols[symbol]{
[注释]:{
符号,f,符号,优先级,从右到左,
argCount:1+(表示法==“中缀”)
},
符号,
regSymbol:symbol.replace(/[\\^$*+.()\\[\]{}]/g,'\\$&'))
+(/\w$/.test(symbol)?“\\b”:”“)//如果是名称,请添加一个分隔符
});
}
last(…a){返回a[a.length-1]}
否定(a){return-a}
加法(a,b){返回
// strip anything other than digits, (), -+/* and .
var str = "12/5*9+9.4*2".replace(/[^-()\d/*+.]/g, '');
alert(eval(str));
function evil(fn) {
  return new Function('return ' + fn)();
}

console.log( evil('12/5*9+9.4*2') ); // => 40.4
function calcMe(str) {
  const noWsStr = str.replace(/\s/g, '');
  const operators = noWsStr.replace(/[\d.,]/g, '').split('');
  const operands = noWsStr.replace(/[+/%*-]/g, ' ')
                          .replace(/\,/g, '.')
                          .split(' ')
                          .map(parseFloat)
                          .filter(it => it);

  if (operators.length >= operands.length){
    throw new Error('Operators qty must be lesser than operands qty')
  };

  while (operators.includes('*')) {
    let opIndex = operators.indexOf('*');
    operands.splice(opIndex, 2, operands[opIndex] * operands[opIndex + 1]);
    operators.splice(opIndex, 1);
  };
  while (operators.includes('/')) {
    let opIndex = operators.indexOf('/');
    operands.splice(opIndex, 2, operands[opIndex] / operands[opIndex + 1]);
    operators.splice(opIndex, 1);
  };
  while (operators.includes('%')) {
    let opIndex = operators.indexOf('%');
    operands.splice(opIndex, 2, operands[opIndex] % operands[opIndex + 1]);
    operators.splice(opIndex, 1);
  };

  let result = operands[0];
  for (let i = 0; i < operators.length; i++) {
    operators[i] === '+' ? (result += operands[i + 1]) : (result -= operands[i + 1])
  }
  return result
}
stringToMath(str);