我在表格中存储了很多条件语句,每个语句都有一些截然不同的格式(if x > Y
,if Z = true
,if 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'
}
};
答案 0 :(得分:2)
正如您可能知道的那样,当您编码它时,它始终有效(只要条件不是空字符串),因为任何非空字符串总是真的。
最好和最安全的方法是编写某种解析器,通过干净地分解并分析它来分析条件。这些通常看起来像:
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;
显然,这是一个简单的例子,但基本过程是一样的。可能还有一些库可以为你处理它。
然后你可以根据需要使用它:
if (resolve('a > b', a, b)) {
// do something
}
您还需要一些逻辑来查看操作数是否为数字,如果是,则使用这些值而不是传入的变量。
我犹豫提供的另一个选择是使用eval()
功能。这个函数通常是一个非常大的,非常糟糕的禁忌,因为它执行任意代码并且可以打开各种安全和逻辑漏洞。但是,有必要讨论适合的场景(比如一个非常小的,快速的Node.js脚本供个人使用)。
const x = 3;
const y = 5;
if (eval('x < y')) {
console.log('condition hit');
}
&#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个解决方案。
eTable['someCondition] = "x > y"
,将其存储为eTable['someCondition] = () => x > y
,然后您可以通过if (eTable[i].condition()) { /* handle true */ } else { /* handle false */ }
简单地调用它。我认为第一个建议可以实现你的目标。