我目前正在编写一个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提供.字符串比较不起作用.需要转换为数字.
你没有显示如何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)
| 归档时间: |
|
| 查看次数: |
169 次 |
| 最近记录: |