有没有办法使比较运算符成为变量
Is there a way to make a comparison operator a variable?
类似于python:使变量等于运算符(+,/,*,-(
我有一些代码,用户可以在其中选择要运行的比较类型,以及要比较的值。我很想知道Javascript中是否有任何方法可以将用户提供的比较值转换为实际的比较,从而允许我执行以下操作:
if (user_val user_comparison other_val) {
do_something();
}
而不必执行以下操作:
if (user_comparison = '<') {
if (user_val < other_val) {
do_something();
}
else if (user_comparison = '<=') {
if (user_val <= other_val) {
do_something();
}
....etc
请注意,如果匹配任何比较,将执行相同的代码。
不,这是不可能的。但是你可以用更好的方式构建你的代码。例如,您可以有一个查找表:
var operator_table = {
'>': function(a, b) { return a > b; },
'<': function(a, b) { return a < b; }
// ...
};
后来:
if(operator_table[user_comparison](user_val, other_val)) {
// do something
}
当然,当表中不存在user_comparison
时,您也应该处理这种情况。
这些还使您能够更好地控制允许和不允许的运算符。
这是@Jesse创建的演示。
假设您正在正确检查用户提供的操作数和运算符,以确保它们包含您想要的数据而不是其他 javascript 可执行代码,您可以将这两个操作数与中间的运算符连接起来,并将其提供给eval()
以使其执行。
现在,eval()
很危险,因为它可以执行任何JavaScript代码。用户可以作为操作员提供可执行的和可能的恶意JavaScript代码,eval()
会对其进行评估。因此,在执行串联时,应在验证操作数是否安全后执行此操作。为了强调这一点,我将用大字体写下计算机安全最重要的原则之一:
所有输入都是邪恶的,除非另有证明。
另外,请注意,eval()
调用 JavaScript 解释器来解释、编译和执行您的代码。这很慢。虽然如果您只是偶尔使用 eval()
,您可能不会注意到任何可观察到的性能问题,但如果您非常频繁地调用eval()
,例如,在每个 keyevent 上,您可能会注意到性能问题。
考虑到eval()
的这些缺点,您可能希望选择更整洁的解决方案,例如Felix Kling发布的解决方案。但是,也可以使用eval()
以安全的方式解决此问题,如下所示:
function compare(a, op, b)
{
// Check that we have two numbers and an operator fed as a string.
if (typeof a != 'number' || typeof b != 'number' || typeof op != 'string')
return
// Make sure that the string doesn't contain any executable code by checking
// it against a whitelist of allowed comparison operators.
if (['<', '>', '<=', '>=', '==', '!='].indexOf(op) == -1)
return
// If we have reached here, we are sure that a and b are two integers and
// op contains a valid comparison operator. It is now safe to concatenate
// them and make a JavaScript executable code.
if (eval(a + op + b))
doSomething();
}
请注意,根据白名单验证输入几乎总是比根据黑名单验证输入更好的主意。有关它的简要讨论,请参阅 https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet#White_List_Input_Validation。
以下是此解决方案的演示: http://jsfiddle.net/YrQ4C/(下面还复制了代码(:
function doSomething()
{
alert('done something!')
}
function compare(a, op, b)
{
if (typeof a != 'number' || typeof b != 'number' || typeof op != 'string')
return
if (['<', '>', '<=', '>=', '==', '!='].indexOf(op) == -1)
return
if (eval(a + op + b))
doSomething();
}
// Positive test cases
compare(2, '<', 3)
compare(2, '<=', 3)
// Negative test cases
compare(2, '>', 3)
compare(2, '>=', 3)
// Attack tests
compare('alert(', '"attack!"', ')')
// Edit: Adding a new attack test case given by Jesse
// in the comments below. This function prevents this
// attack successfully because the whitelist validation
// for the second argument would fail.
compare(1, ';console.log("executed code");2==', 2)
编辑:杰西测试用例的演示包括:http://jsfiddle.net/99eP2/
- 在 Jquery/Javascript 中使用多个 OR (||) 运算符时如何设置变量
- 在Javascript中,变量前面的+运算符是什么
- 如何将运算符分配给变量
- 我需要添加一个变量而不添加(使用算术运算符)
- 变量和数学运算符
- JavaScript 中带有运算符的变量链式赋值
- 一个变量声明中多个运算符的重要性
- 将 JavaScript 比较运算符与变量一起使用
- 为什么后递增/递减运算符对循环中的变量没有任何影响
- 有没有办法使比较运算符成为变量
- 用javascript中的变量替换运算符
- math.js中的变量名和限制运算符
- 三元运算符赋值优先级为变量
- 为什么jQuery源代码如此频繁地使用逗号运算符进行变量赋值
- Javascript:无法获得变量和以使用加法运算符
- "||"运算符在为变量赋值时不起作用
- 将三元运算符转换为传统if语句时未定义的变量
- 如何使用逻辑运算符填充变量?
- 条件三元运算符给出错误:应为赋值或函数调用,但在设置变量时却看到了表达式
- 如何使用 javascript 将运算符存储在变量中