是否存在> =和< =的问题以及JS中的eval函数?

时间:2012-09-21 09:08:29

标签: javascript eval

我目前正在编写一个JS规则引擎,它一度需要使用eval()函数来评估布尔表达式。

首先,我构建一个等式:

var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "relation.value";

relation.relatedTrigger.previousValue 是我要比较的值。

relation.operator 是运营商(" ==","!=",< =,"< ",">",> =")。

relation.value 是我要与之比较的值。

然后我只是将这个字符串传递给eval函数,它返回true或false:

return eval(equation);

除了> =和< =之外,这非常合适(使用单词和数字)或所有运算符。例如。在评估等式时:

relation.relatedTrigger.previousValue <= 100

当previousValue = 0,1,10,100&amp;所有负数,但两者之间的所有内容都是假的。

我非常感谢任何人帮助回答我的问题或帮助我找到替代解决方案。

此致

奥吉尔。

P.S。我不需要就eval()函数的不安全性发表演讲。任何给予relation.relatedTrigger.previousValue的值都是预定义的。

编辑:这是完整的功能:

function evaluateRelation(relation)
{
console.log("Evaluating relation")
var currentValue;

//if multiple values
if(relation.value.indexOf(";") != -1)
{
    var values = relation.value.split(";");
    for (x in values)
    {

        var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "values[x]";
        currentValue = eval(equation);
        if (currentValue)
            return true;
    }
    return false;
}

//if single value
else
{
    //Evaluate the relation and get boolean
    var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "relation.value";
        console.log("relation.relatedTrigger.previousValue " + relation.relatedTrigger.previousValue);
    console.log(equation);
    return eval(equation);
}
}

答案:KennyTM在下面提供。字符串比较不起作用。需要转换为数字。

3 个答案:

答案 0 :(得分:5)

您没有显示如何获得relation.relatedTrigger.previousValue,但我猜这个变量的类型仍然是一个字符串。在这种情况下,右侧将被视为字符串。字符串比较符合您提到的所有特征:

>>> '-213' <= '100'
true
>>> '0' <= '100'
true
>>> '1' <= '100'
true
>>> '2' <= '100'
false
>>> '10' <= '100'
true
>>> '13' <= '100'
false

您需要确保relation.relatedTrigger.previousValue是一个数字。一种解决方案是在比较中使用一元+运算符,例如

+relation.relatedTrigger.previousValue <= 100

这与eval无关。问题是Javascript过于自由的隐式转换。


编辑:顺便说一句,您可以使用函数字典而不是eval。这更快,也更安全。请参阅http://jsperf.com/eval-vs-function-map

var fmap = {
    '>=': function(a, b) { return a >= b; },
    ...
};

fmap[relation.operator](+relation.relatedTrigger.previousValue, 
                        +relation.value);

答案 1 :(得分:1)

比较字符串而不是数字。

确保relation.relatedTrigger.previousValuerelation.value是数字。

"11"&gt; "100":因为11按字母顺序排在100之后。

11&lt; 100按数字顺序。

答案 2 :(得分:0)

var relation = {'relatedTrigger':{'previousValue':"7"}, 'operator':'<=', 'value': "100"};

var equation = "parseFloat(relation.relatedTrigger.previousValue)" + " " + relation.operator + 
    " " + "parseFloat(relation.value)"; 

alert(equation + ", " + eval(equation));

这实际上是你最终得到的结果,确保数值的额外步骤,而不是字符串传递似乎工作。