作为输入验证的一种形式,我需要强制一个字符串'9>6'来评估一个布尔值.
除了评估字符串,我似乎无法找到解决方法.
我一直都听说过eval的邪恶(特别是因为我正在验证表单输入),关于它可以评估任何脚本和性能问题的事实.
但....
在我的案例中是否有任何替代方案(处理关系运算符)?
var arr = ['<9', '>2'];
var check = function (a) {
return arr.every(function (x) {
var string = '';
string += a + x;
try {
return eval(string);
} catch (e) {
return false;
}
});
};
console.log(check('3'))
Run Code Online (Sandbox Code Playgroud)
我可以看到三件事需要改进:
a您应该直接引用变量,以便可以与值的真实形式进行比较,而不是对值进行字符串化并将其连接到表达式a。否则你可能会出现奇怪的行为。
return eval("a " + x);
Run Code Online (Sandbox Code Playgroud)由于您可能会check多次使用,因此您不应eval每次都调用(甚至每次调用多次)。您可以将字符串组成一个大&&表达式,甚至更好的是,您可以预先将条件编译为单个函数,这样您就根本不必eval从内部调用check。
您应该考虑使用Function构造函数而不是eval.
有了这些,您的代码可能如下所示:
var arr = ['<9', '>2'];
var check = new Function("a", "return "+arr.map(function(x) {
return "a"+x;
}).join(" && ")+";");
console.log(check.toString()); // function anonymous(a) { return a<9 && a>2; }
console.log(check('3'));
Run Code Online (Sandbox Code Playgroud)
或这个:
var arr = ['<9', '>2'];
var fns = arr.map(function(x) {
return new Function("a", "return a "+x+";");
});
function check(a) {
return fns.every(function(f) {
return f(a);
});
}
console.log(check('3'));
Run Code Online (Sandbox Code Playgroud)
当然,我希望这arr不是由用户控制的(或者更糟糕的是,不是当前用户控制的);如果您希望用户输入这些条件,您应该确保明确将它们列入白名单,或者立即使用更复杂的表达式语法/解析器/评估器。
除非是这种情况,eval(或者就此而言,Function)并不完全是邪恶的,它只是缩短(并可能简化)您的代码。您也可以编写出成熟的函数(如 Nit 和 peterh 建议的那样)。
| 归档时间: |
|
| 查看次数: |
679 次 |
| 最近记录: |