有没有办法让比较运算符成为变量?

时间:2012-05-14 21:21:07

标签: javascript comparison operators

python: make a variable equal an operator (+,/,*,-)类似

我有一些代码,用户可以选择要运行的比较类型,以及要比较的值。我很想知道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

请注意,如果匹配任何比较,将执行相同的代码。

3 个答案:

答案 0 :(得分:13)

不,这是不可能的。但是您可以更好地构建代码。例如,您可以拥有一个查找表:

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的情况。

这些还可以让您更好地控制允许和不允许的操作符。

以下是由DEMO创建的@Jesse

答案 1 :(得分:5)

假设您正在检查用户提供的操作数和运算符以确保它们包含您想要的数据而不是其他javascript可执行代码,您可以将两个操作数与运算符连接在一起并将其提供给{{1}让它执行。

现在,eval() 危险,因为它可以执行任何JavaScript代码。用户可以提供可执行的和可能是恶意的JavaScript代码作为运算符,eval()将对其进行评估。因此,在进行连接时,应在验证操作数是否安全后执行此操作。为了强调这一点,我将用大字体编写计算机安全最重要的原则之一:

  

除非另有证明,否则所有输入都是邪恶的。

另外,请注意eval()调用JavaScript解释器来解释,编译和执行代码。这很慢。如果您偶尔使用eval(),可能不会发现任何可观察到的性能问题,但如果您经常(例如)在每个关键事件上调用eval(),您可能会注意到性能问题。

考虑到eval()的这些缺点,您可能想要寻找像Felix Kling发布的更简洁的解决方案。但是,也可以使用eval()以安全的方式解决此问题,如下所示:

eval()

请注意,针对白名单验证输入几乎总是比针对黑名单验证更好。有关它的简要讨论,请参见https://www.owasp.org/index.php/Input_Validation_Cheat_Sheet#White_List_Input_Validation

以下是此解决方案的演示:http://jsfiddle.net/YrQ4C/(代码也转载如下):

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();
}

编辑:使用Jesse的测试用例进行演示:http://jsfiddle.net/99eP2/

答案 2 :(得分:-2)

由于@Susam Pal代码不起作用。我发布了一个工作版

<html>
  <head>
   <script>
       function CompareSomething(val1, compareString, val2) {  
           eval('if(' + val1 + ' ' + compareString + ' ' + val2 + '){conditionPassed();}else{conditionFailed();}'); 
  }
  function compare(a, op, b) { 
      if (eval(a + op + b))
          conditionPassed();
      else
         conditionFailed();
  }
  function conditionPassed() {
      alert('condition passed');
  }
  function conditionFailed() {
      alert('condition failed');
  }
    </script>
  </head> 
<body>
a:<input id='txt1' type="text" />&nbsp;op:<input id='txt2' type="text" />&nbsp;b:<input id='txt3' type="text" /><br/>
<button id='compare'  onclick='CompareSomething(document.getElementById("txt1").value,document.getElementById("txt2").value,document.getElementById("txt3").value)'>Compare Esen Method</button><br/>
<button id='compare'  onclick='Compare(document.getElementById("txt1").value,document.getElementById("txt2").value,document.getElementById("txt3").value)'>Compare Susam Method</button>
  </body>
 </html>