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

Aug*_*ier 6 javascript eval

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

首先,我构建一个方程式:

var equation = "relation.relatedTrigger.previousValue" + " " + relation.operator +
        " " + "relation.value";
Run Code Online (Sandbox Code Playgroud)

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

relation.operator是运算符("==","!=",<=,"<",">",> =").

relation.value是我想要比较的值.

然后我只是将此字符串传递给eval函数,它返回true或false,如下所示:

return eval(equation);
Run Code Online (Sandbox Code Playgroud)

除了> =和<=之外,这绝对可以(使用单词和数字)或所有运算符.例如,在评估等式时:

relation.relatedTrigger.previousValue <= 100
Run Code Online (Sandbox Code Playgroud)

当previousValue = 0,1,10,100和所有负数时它返回true,但对于其间的所有内容都返回false.

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

问候,

奥吉尔.

PS我不需要关于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);
}
}
Run Code Online (Sandbox Code Playgroud)

答案:由KennyTM提供.字符串比较不起作用.需要转换为数字.

ken*_*ytm 5

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

>>> '-213' <= '100'
true
>>> '0' <= '100'
true
>>> '1' <= '100'
true
>>> '2' <= '100'
false
>>> '10' <= '100'
true
>>> '13' <= '100'
false
Run Code Online (Sandbox Code Playgroud)

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

+relation.relatedTrigger.previousValue <= 100
Run Code Online (Sandbox Code Playgroud)

这与此无关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);
Run Code Online (Sandbox Code Playgroud)