我有一个要求,即用户可以提供任意语句,这些语句可以存储在一个函数中,稍后调用以获得返回值。一个简单的例子是 userInput
可能是
var x = 10;
x;
我会通过以下方式存储它
var callback = function() {
return eval(userInput);
}
然后运行 callback()
按预期返回 10
。
但是,我还需要用显式返回语句来支持这种情况,即 userInput
可能是
var x = 10;
return x;
在这种情况下,上面的 eval 方法将失败并返回 SyntaxError: return not in function
。相反,我可以将回调存储为
var callback = new Function(userInput);
我的问题是,我想根据“获取显式返回值,否则获取上次执行语句的结果”的规则组合这两种方法。特别是这不能通过在回调创建时分析代码来完成,因为用户可能会做一些奇怪的事情,比如
if(envVar < 10)
return a;
b * 0.5;
两者结合。
关于如何构建 callback
函数的创建以适应这些可能的输入,有什么想法吗?不幸的是,不可能对用户强制执行一种样式或另一种样式。
更新以回答下面的一些评论。
建议的一种解决方案是搜索返回 token 并在 new Function
和 eval
之间进行选择。这不适用于我的最后一个示例,请参阅 http://jsfiddle.net/ZGb6z/2/ - out4 应该是 "no"
但由于未返回最后执行的语句而最终未定义。
另一个建议是修改用户输入以在未找到时在最后一行添加显式返回。不幸的是,不可能知道哪个语句将最后执行。考虑
var x = 10;
switch(x) {
case 10:
100;
break;
default:
200;
break;
}
调用时它应该返回 100
,但需要认真分析以确定将任意代码的返回值放在哪里。
最佳答案
只需使用try
catch
,操作输入对您来说会非常痛苦,而try
catch
在这一点上真的不能让你的代码更迟钝了。
var failback = function () {
try {
return eval(userInput);
} catch (e) {
return Function(userInput);
}
};
我真正的建议是投资一个解析器,有点像 how Angular does it .这种事情会阻止您的用户为所欲为,引入攻击向量,yadda,yadda,yadda。
关于javascript - 从任意评估代码中获取返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20798827/