在if语句中循环变量条件

时间:2018-01-23 20:38:54

标签: javascript loops variables if-statement

我在表格中存储了很多条件语句,每个语句都有一些截然不同的格式(if x > Yif Z = trueif Z <= 12等)。我以这样的方式存储它们,以便我可以轻松遍历条件语句并执行函数来更新相关属性。

但是,正如我发现的那样,它不会让我将条件语句存储为变量。意思是,我必须显式声明每个条件语句,而不是声明它一次并遍历所有可能的条件。

有没有办法做到这一点我失踪了,或者只是不理解?

在下面的示例中,我想使用eTable[i].condition循环遍历该位置存储的所有条件。这有可能吗?

function checkEvents () {
    eventConditionLength = Object.keys(eTable).length;

    for (let i = 0; i < eventConditionLength; i++) {
        if (eTable[i].condition) {
            alert(i);
        };
    };
};

ETABLE

var eTable = {
0: {
        sceneTitle: '', //Descriptive/organizational only
        sceneHeader: ['Event 1', 'Event 1', 'Event 1'],
        sceneImage: ['/images/1.jpg', '/images/2.jpg', '/images/3.jpg'],
        sceneText: ['Test Scene Text 1', 'Test Scene Text 1', 'Test Scene Text 1'],
        sceneControls: ['myFunction1', 'myFunction2', 'myFunction3'],
        visible: false,
        completed: false,
        condition: 'cEvent == "e0002"'
    },
1: {
        sceneTitle: '', //Descriptive/organizational only
        sceneHeader: ['Event 1', 'Event 1', 'Event 1'],
        sceneImage: ['/images/1.jpg', '/images/2.jpg', '/images/3.jpg'],
        sceneText: ['Test Scene Text 1', 'Test Scene Text 1', 'Test Scene Text 1'],
        sceneControls: ['myFunction1', 'myFunction2', 'myFunction3'],
        visible: false,
        completed: false,
        condition: 'stat1 > 15 && completed == false'
    }
};

4 个答案:

答案 0 :(得分:2)

正如您可能知道的那样,当您编码它时,它始终有效(只要条件不是空字符串),因为任何非空字符串总是真的。

最好和最安全的方法是编写某种解析器,通过干净地分解并分析它来分析条件。这些通常看起来像:

&#13;
&#13;
const condition = 'x < y';

/**
 * condition is the full string
 * a is the left-hand variable, if needed
 * b is the right-hand variable, if needed
 */
function resolve(condition, a, b) {
  // regex will get the non-alphanumeric operator and the left and right operands
  const [, left, operator, right] = condition.match(/([a-z0-9]+)\s*([^a-z0-9\s]+)\s*([a-z0-9]+)/);
  
  // you'd need a case for each vald operator
  switch (operator) {
    case '<':
      return a < b;
  }
}

console.log(resolve(condition, 3, 5));
console.log(resolve(condition, 5, 3));
&#13;
&#13;
&#13;

显然,这是一个简单的例子,但基本过程是一样的。可能还有一些库可以为你处理它。

然后你可以根据需要使用它:

if (resolve('a > b', a, b)) {
  // do something
}

您还需要一些逻辑来查看操作数是否为数字,如果是,则使用这些值而不是传入的变量。

我犹豫提供的另一个选择是使用eval()功能。这个函数通常是一个非常大的,非常糟糕的禁忌,因为它执行任意代码并且可以打开各种安全和逻辑漏洞。但是,有必要讨论适合的场景(比如一个非常小的,快速的Node.js脚本供个人使用)。

&#13;
&#13;
const x = 3;
const y = 5;

if (eval('x < y')) {
  console.log('condition hit');
}
&#13;
&#13;
&#13;

这将有效,在您的示例中,只需将您的eTable[i].condition包装在eval中(并确保它所寻找的变量在当前范围内声明)。

同样,这通常非常糟糕,所以如果您使用它,请务必在继续阅读之前阅读所有相关内容。

答案 1 :(得分:1)

您可以使用eval()

function checkEvents () {
    eventConditionLength = Object.keys(eTable).length;


    for (let i = 0; i < eventConditionLength; i++) {
        if (eval(eTable[i].condition))
        {
            alert(i);
        };
    };
};

正如瓦桑在评论中指出的那样,few downsides to eval需要注意。

答案 2 :(得分:0)

我相信你将字符串传递给if条件语句,因为eTable[i].condition它不是逻辑条件,它只是字符串(我相信你有字符串)。您需要使用eval()评估字符串作为代码:

for (let i = 0; i < eventConditionLength; i++) {
    if (eval(eTable[i].condition)) {
        alert(i);
    };
};

P.S。:eval()代码风格不好而且很危险。小心。

答案 3 :(得分:0)

我可以为您提供2个解决方案。

  1. 更好的方法,存储功能。每个函数都会保留您的条件,例如,而不是存储eTable['someCondition] = "x > y",将其存储为eTable['someCondition] = () => x > y,然后您可以通过if (eTable[i].condition()) { /* handle true */ } else { /* handle false */ }简单地调用它。
  2. 糟糕的方法,使用eval()并存储代表js代码的字符串来执行。
  3. 我认为第一个建议可以实现你的目标。