我有一个包含一些条件的字符串,例如:
var str = "this.demoModel.active == '1' && this.demoModel.span > 5 || ..."
javascript 中是否有一种直接的方法来解析它们,以便它们像一组条件一样工作。就像是:
if (JSON.parse(str) {})
。 ??
原文由 Ashish Ranjan 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个包含一些条件的字符串,例如:
var str = "this.demoModel.active == '1' && this.demoModel.span > 5 || ..."
javascript 中是否有一种直接的方法来解析它们,以便它们像一组条件一样工作。就像是:
if (JSON.parse(str) {})
。 ??
原文由 Ashish Ranjan 发布,翻译遵循 CC BY-SA 4.0 许可协议
有,但使用它们通常是最后的手段: eval
和 Function
构造函数。 eval
在调用 eval
的上下文中从字符串输入运行代码。 Function
构造函数从字符串创建一个函数。自然地,在这两种情况下,这意味着 您必须信任 string 的来源,因为它可以包含任意代码,并且您很乐意在代码的上下文中运行它。因此,例如,您不会从用户 A 获取一个字符串,然后在用户 B 的浏览器中运行它——这会使用户 B 对用户 A 的攻击敞开大门。(对于“浏览器”替代“会话”或其他任何内容,问题在像 Node 这样的环境中的服务器端和浏览器中的客户端一样真实——也许更是如此。)
如果您接受来自用户的字符串并在他们自己的浏览器/会话/上下文中运行它,那很好。
这是一个例子:
function Foo() {
this.demoModel = {
active: "1",
span: 7
};
}
Foo.prototype.run = function(str) {
if (eval(str)) {
console.log("Yes");
} else {
console.log("No");
}
};
var f = new Foo();
f.run("this.demoModel.active == '1' && this.demoModel.span > 5");
f.run("this.demoModel.active == '0' && this.demoModel.span < 5");
您还可以使用 Function
构造函数,然后使用正确的 this
调用它:
function Foo() {
this.demoModel = {
active: "1",
span: 7
};
}
Foo.prototype.run = function(str) {
var testfunc = new Function("return " + str);
if (testfunc.call(this)) {
console.log("Yes");
} else {
console.log("No");
}
};
var f = new Foo();
f.run("this.demoModel.active == '1' && this.demoModel.span > 5");
f.run("this.demoModel.active == '0' && this.demoModel.span < 5");
如果您 必须 这样做,请尽可能使用 Function
构造函数而 eval
,因为它无法访问您使用它的范围内的所有内容,但它们都是强大的工具你需要警惕。
原文由 T.J. Crowder 发布,翻译遵循 CC BY-SA 3.0 许可协议
13 回答12.7k 阅读
7 回答1.9k 阅读
3 回答1.1k 阅读✓ 已解决
2 回答1.1k 阅读✓ 已解决
6 回答813 阅读✓ 已解决
6 回答1k 阅读
2 回答1.3k 阅读✓ 已解决
一般来说,你应该尽量避免陷入这种情况:如果可能的话,应该避免将 JavaScript 存储在字符串中以供以后评估。根据您的实际情况,您可以考虑以下选项:
1.使用模板文字:
它们在实际使用中受到限制,因为它们与使用它们的脚本一起被解析,但 它们也是安全的:
分配此字符串后,它将立即计算其中的
${ }
部分。因此,如果评估可以立即发生,这只是一个解决方案,因为您不能将其存储在字符串中,然后期望稍后触发评估。
所以它与以下内容没有太大区别:
2.通过回调延迟求值
一种解决方法是定义一个函数来评估模板文字或表达式,如下所示:
…并且您可以传递该函数,例如作为回调:
…然后 doSomething 可以这样调用它,绑定上下文,以便
this
具有适当的值:3.嵌套对象数据结构
另一种选择是为表达式创建一个对象结构,例如:
这是一个嵌套数组,其中顶层将具有必须一起进行“或”运算的规则,而内层将进行“与”运算。
然后编写一个函数来处理这个结构。 比较 名称可以映射到代码中的函数,如下所示:
因此,要评估 规则 数组中的一个对象,您可以使用:
这个 规则 结构可以很容易地保存和加载为 JSON 字符串。