javascript - 简化的动态算术运算符

标签 javascript eval

我正在重新审视我不久前处理过的这个旧项目,我想避免使用 if 语句和 switch block 来呈现一个简单的计算,其中运算符 ( +/-///* )可以是任何东西。

我正在通过ajax从数据库中检索数据(安全插入),以及用户输入的测试用例(同样,通过验证精心保护)。效果很好,耶,太棒了。现在我们来谈谈我听过很多次的恶魔。 eval()

如果您花时间阅读,使用 V8 引擎之类的现代浏览器可以缓存编译后的 eval。人们说它通过注入(inject)创造了漏洞。如果您提供有效的验证并避免任何关键的应用程序错误结构,它怎么会有害呢?

//note I'm using var just for clarity, this is NOT the declaration or assignment statment
//also note the variables are stored in an array because the condition can be dynamic in size, but that's overhead for now

var firstNum = 50;
var secondNum = 100;
var operator = "+";
var condition = firstNum+operator+secondNum;

if (eval(condition) > 149) { //not the real condition, just an example
    console.log("Success");
}

这还是不安全吗?它比 switch 语句更有效率吗?嵌套 if 语句?如果性能不是问题并且您确实知道自己在做什么,那么 eval() 可以很好,而不是..等待它.. evil()

注意:是的,我已经看到了有关 eval() 的其他问题,但我仍然没有找到它存在的原因,因为人们把它当作麻风病人对待。

这基本上可以归结为:处理数学运算符不是静态值的情况的最佳方法是什么?

最佳答案

eval 有害的部分原因是

  • 您必须非常小心,以避免代码注入(inject)。
  • 大多数 IDE 无法捕获动态构建的字符串中愚蠢的语法错误。
  • 从历史上看,它在性能方面一直很糟糕。
  • 这基本上是用大锤拍苍蝇,这是许多其他原因的主要原因。非常非常少的情况可以从如此大的灵 active 中受益,而且大多数情况只会变得更糟。

在这种情况下,你可以这样做

var operators = {
    '+' : function(a, b) { return a + b; },
    '-' : function(a, b) { return a - b; },
    '*' : function(a, b) { return a * b; },
    '/' : function(a, b) { return a / b; },
};

var firstNum = 50;
var secondNum = 100;
var op = operators['+'];

if (op(firstNum, secondNum) > 149) {
    console.log('Success');
}

并最终获得您在eval中寻找的所有活力,并且没有任何缺点。您可以准确定义要允许的操作,而且,您甚至不限于中缀运算符 - 例如,您可以使用“max”运算符或“round”。

关于javascript - 简化的动态算术运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20897581/

相关文章:

python - 检查是否可以在 Python 中评估字符串(使用 eval())

variables - 目标下的makefile变量赋值

foreach - GNU Make 失败,foreach->eval->call

javascript - Laravel 字符串本地化和 AngularJS

javascript - 按名称获取对象作为不带 eval 的字符串

php - 如何在不转到 php.ini 文件的情况下禁用 eval 函数?

Ruby 评估没有评估?

javascript - 验证时,下拉框应该是彩色的,而不是警告框

javascript - meteor JS + PostgreSQL

javascript - ajax 调用后事件委托(delegate)中断