我想定义一个函数,它将充当while
语句(带有一些插件,但为了简单起见,我将在这里展示一个基本的包装器)。因此,条件作为第一个参数,并且在每个循环中执行的回调作为第二个参数。
我刚开始使用这个版本:
const wrappedWhile = (conditions, callback) => {
let avoidInfinite = 0;
while (conditions) {
callback();
if (avoidInfinite >= 10) {
console.log('breaking while statement for avoiding infinite loop');
break;
}
avoidInfinite++;
}
};
let i = 0;
wrappedWhile(i < 5, () => {
console.log('log from callback: i =', i);
if (i >= 5) {
console.log('the loop continues whereas it should stop');
}
i++;
});
从逻辑上讲,它预计会在i >= 5
时停止。但是conditions
参数在wrappedWhile
函数中是一个简单的布尔值,所以它始终是true
,因为i
在调用时小于5
。
然后,我提出了另一个版本,其中conditions
在循环的每次迭代中被评估:
const wrappedWhile = (conditions, callback) => {
while (Function('return ' + conditions + ';')()) {
callback();
}
};
let i = 0;
wrappedWhile('i < 5', () => {
console.log('log from callback: i =', i);
i++;
});
但是,如果我没有错,Function
正在使用eval()
工作,我们所有人都曾听说使用eval()
对代码注入并不是很安全。
现在我的问题很简单:是否有更安全的替代方案可以实现我想要实现的目标?
经过一些研究,我发现了一个link,它显示了一种在沙箱环境中进行评估的方法,但我不知道它是否是好方法。
您应该将函数作为条件传递并在while循环中调用它
const wrappedWhile = (conditions, callback) => {
let i = 0;
while (conditions(i)) {
callback(i);
if (i >= 10) {
console.log('breaking while statement for avoiding infinite loop');
break;
}
i++;
}
};
wrappedWhile((i) => (i < 5), (iteration) => {
console.log('log from callback: i =', iteration);
});